2014-08-29 96 views
-1

爲什麼wait()在同步塊內?我的意思是,只有一個線程將進入同步塊,那麼另一個線程如何執行wait()指令?爲什麼在裏面等待同步?

+2

哪'synchronized'塊你在說什麼?你的問題真的不清楚(也很廣泛)...... – BackSlash 2014-08-29 12:49:16

+0

沒有任何答案,無論是在這裏還是在副本中,都提到了一個典型的原因:「notifyAll」將會是一團糟,無需在繼續之前重新獲得鎖定。 – 2014-08-29 13:22:18

+0

這是因爲在你等待某件事之前,你必須確定事情還沒有發生。你必須確保它不會在你等待時發生。所以你必須持有一個鎖來等待某件事 - 這個鎖可以保護你等待狀態改變的東西。 – 2016-03-30 09:35:59

回答

2
  1. 同步關鍵字用於獨佔訪問。
  2. 要使方法同步,只需將synchronized關鍵字添加到其聲明中即可。然後,同一對象上的同步方法的任何兩次調用都可以相互交錯。
  3. 同步語句必須指定提供內部鎖定的對象。使用同步(this)時,您必須避免同步其他對象方法的調用。
  4. wait()通知調用線程放棄監視器並進入休眠狀態,直到某個其他線程進入相同的監視器並調用notify()。
  5. notify()喚醒在同一個對象上調用wait()的第一個線程。

例子:

public class ThreadA { 
    public static void main(String[] args){ 
     ThreadB b = new ThreadB(); 
     b.start(); 

     synchronized(b){ 
      try{ 
       System.out.println("Waiting for b to complete..."); 
       b.wait(); 
      }catch(InterruptedException e){ 
       e.printStackTrace(); 
      } 

      System.out.println("Total is: " + b.total); 
     } 
    } 
} 

class ThreadB extends Thread{ 
    int total; 
    @Override 
    public void run(){ 
     synchronized(this){ 
      for(int i=0; i<100 ; i++){ 
       total += i; 
      } 
      notify(); 
     } 
    } 
} 

得到它:http://www.programcreek.com/2009/02/notify-and-wait-example/

+0

爲什麼'synchronized(this)'在'ThreadB'中被調用?不僅線程本身調用運行,並且沒有其他線程? – Artemkller545 2014-08-29 12:56:51

+0

當我嘗試運行沒有這個同步塊,我得到了一個java.lang.IllegalMonitorStateException,這很有趣。當通過b同步threadA時,它需要保證notify()也被同步,或者其他實例可以調用notify。 – 2014-08-29 13:17:14

0
Why is wait() inside of a synchronized block? 

因爲線程需要有你呼籲wait()對象的監視器,在一個synchronized方法的情況下,this對象。

I mean, only one thread will enter the synchronized block, so how can the other 
thread execute the wait() instruction? 

它不能,只有同步塊內的線程可以執行wait(),允許其他線程進入同步塊。

+0

「[foo。]爲什麼[需要]在[synchronized(foo)]內部等待?」你基本上說,「因爲它需要。」 _why_會更好的回答。完整的答案對於這個空間來說太大了,但簡而言之, 'foo.wait()'的調用者應該等待一些明確的,可測試的條件,並且爲了避免「丟失的通知」,可以測試或改變條件的每個代碼塊(包括服務員)應該同步同一把鎖。 Java不能強制代碼塊是同步的,但是它對等待的塊()和通知()的塊是這樣做的。 – 2014-08-29 13:19:25