[英]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.