我有一个同步方法。然后我将启动一个长时间操作的线程,子线程也有一个synchronized方法,但子线程中的synchronized方法将保持同步方法的锁定,这将导致我的应用程序。
我的代码是:
import java.util.Date;
public class ThreadTest {
static MQTTThread mThread;
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println("the " + i + " - restart time = "
+ new Date());
restart(i);
}
}
private static synchronized void restart(int i) {
System.out.println("the " + i + " - restart excute " + new Date());
if (null != mThread) {
if (!mThread.isAlive()) {
try {
System.out
.println("Action:restartConnectThread in mThread.runFlag)");
mThread = new MQTTThread();
mThread.setName("MQTTThread");
mThread.start();
// mqttExecutor.execute(mThread);
} catch (Exception e) {
System.out.println("!mThread.runFlag");
}
} else {
System.out.println("Action:restartConnectThread - CONNECTING");
}
} else {
try {
System.out
.println("Action:restartConnectThread in null thread");
mThread = new MQTTThread();
mThread.setName("MQTTThread");
mThread.start();
} catch (Exception e) {
System.out.println("null mThread");
}
}
}
private static class MQTTThread extends Thread {
public void run() {
connectToServer();
System.out.println("connected");
}
}
public static synchronized void connectToServer() {
try {
System.out.println("Thread.sleep " + new Date());
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
这是同步方法的标准行为。
查看http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
对两个同步方法的调用是不可能的 相同的对象交错。当一个线程正在执行同步时 对象的方法,调用synchronized的所有其他线程 同一个对象块的方法(暂停执行)直到第一个 线程是用对象完成的。
所以代码
public synchronized void method() {
}
相当于
public void method() {
synchronized (this) {
}
}
出于您的目的,您应该为connectToServer
和restart
方法使用不同的锁定对象
UPD。对不起,我错过了,你的方法是静态的。在这种情况下specification 8.4.3.6
synchronized方法在执行之前获取监视器。 对于类(静态)方法,使用与方法类的Class对象关联的监视器。
所以你不能同时运行一个类的两个同步方法,即使它们是静态的
答案 1 :(得分:0)
阻止主UI线程5秒或更长时间会导致ANR。
来自Anr Message with synchronized method
可能因为:
而发生了Thread.sleep(20000);
避免锁定主UI线程。