[英]Code in synchronized block
放置timlesProc(100);
有什么区别timlesProc(100);
内部或外部synchronized
块,如ThreadA中所示的注释行。
根据我的理解,这没有什么区别,因为两个线程都处于运行模式,并且可以同时执行。 但是根据实验,当timlesProc(100);
内部synchronized
-始终先运行,然后运行b.sync.wait();
没有“永远等待”的问题。 当timlesProc(100);
外部synchronized
-我总是得到“永远的等待”。 为什么会这样,或者我的理解不正确?
class ThreadA {
public static void timlesProc(int count)
{
for(int i=0;i<count;i++)
{
System.out.println(Thread.currentThread().getName()+" "+ Integer.toString(i));
}
}
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
//timlesProc(100);
synchronized(b.sync)
{
timlesProc(100);
try
{
System.out.println("Waiting for b to complete...");
b.sync.wait();
System.out.println("waiting done");
} catch (InterruptedException e) {}
}
}
}
class ThreadB extends Thread {
Integer sync = new Integer(1);
public void run() {
synchronized(sync)
{
sync.notify();
System.out.println("notify done");
}
}
}
您有比赛条件。 如果timlesProc
方法超出了synchronized
,这是非常可能的 ,你将有一个上下文切换,另一个Thread
就可以执行获取锁,并通知main
线程(即使它不是在等待)。 那当你到
b.sync.wait();
您将永远等待,因为没有任何东西可以notify()
。
如果你把timlesProc
内部synchronized
,你到达wait()
然后得到通知。 然后程序结束。
有关程序永久等待的另一种可能性,请参阅Cruncher的答案 。
实际上,即使timlesProc
调用位于同步块内,也仍然存在竞争状态,发生的可能性较小。
如果b.start()
发生了,并且它在主线程之前获取了同步锁,那么它将仍然首先通知,从而引起Sotirios Delimanolis在其答案中提到的相同问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.