簡體   English   中英

同步塊中的代碼

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM