[英]why synchronized method in the sub thread hold the lock of main thread
I have a synchronized method. 我有一个同步方法。 then I will start a Thread with long time operation, the sub-thread also have a synchronized method, But the synchronized method in sub thread will hold the lock of the synchronized method which will cause anr in my appliction. 然后我将启动一个长时间运行的线程,子线程也有一个同步方法,但是子线程中的同步方法将持有该同步方法的锁,这会在我的应用中引起麻烦。
My code is: 我的代码是:
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();
}
}
}
It is standard behavior of synchronized methods. 它是同步方法的标准行为。
Look at http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html 查看http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
it is not possible for two invocations of synchronized methods on the same object to interleave. 同一对象上的两个同步方法调用不可能交错。 When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. 当一个线程正在执行对象的同步方法时,所有其他调用同一对象块的同步方法的线程(挂起执行),直到第一个线程对该对象完成。
So code 所以代码
public synchronized void method() {
}
is equivalent to 相当于
public void method() {
synchronized (this) {
}
}
For your purposes you should use different lock-objects for connectToServer
and restart
methods 为了您的目的,您应该为connectToServer
和restart
方法使用不同的锁定对象
UPD. UPD。 Sorry, I missed, that your methods are static. 对不起,我想念您的方法是静态的。 In this case specification 8.4.3.6 在这种情况下, 规范8.4.3.6
A synchronized method acquires a monitor before it executes. 同步方法在执行之前先获取一个监视器。 For a class (static) method, the monitor associated with the Class object for the method's class is used. 对于类(静态)方法,使用与该方法的类的Class对象关联的监视器。
So you can not run two synchronized methods of a class simultaneously, even if they are static 因此,即使它们是静态的,也不能同时运行一个类的两个同步方法
Blocking the main UI thread for 5 secods or more causes the ANR. 将主UI线程阻塞5秒或更长时间会导致ANR。
from Anr Message with synchronized method 从Anr Message使用同步方法
Maybe that's happening because of: 可能是因为:
Thread.sleep(20000);
Avoid to lock the main UI thread. 避免锁定主UI线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.