*
          Condition只是一個接口,怎么可以直接調用它的方法呢?于是查源碼(發現這個東西才是最徹底的),從ReentrantLock開始,
          ReentrantLock.newCondition()
          -
          -
          -
          看到了詳細的方法實現 ^_^
          1. 兩三個線程同時修改某個對象,如果僅由訪問先后來決定結果的話,會出現各種結果。這種情況被稱為race condition。
          2. 防止這種情況的發生,必須知道如何同步訪問(synchronize the access)。
          3. javap -c -v ClassName 可以反編譯一個.class文件。
          4. 鎖住對象
          早期版本的Java使用synchronized關鍵詞,JDK5以后引入了ReentrantLock類。
          使用ReentrantLock類保護代碼塊的基本輪廓:
          myLock.lock(); // a ReentrantLock object
          try
          {
          critical section
          }
          finally
          {
          myLock.unlock(); // make sure the lock is unlocked even if an exception is thrown
          }
          這樣第一個線程調用lock方法鎖住myLock后,第二個線程調用lock方法就會被block,并且得等到第一個線程調用myLock.unlock()后才能繼續。
          ReentrantLock類允許被多次鎖定,它記錄了呼叫的嵌套形式。大致是這個意思,原文是

          The lock is called reentrant because a thread can repeatedly acquire a lock that it already owns. The lock keeps a hold count that keeps track of the nested calls to the lock method. The thread has to call unlock for every call to lock in order to relinquish the lock. Because of this feature, code that is protected by a lock can call another method that uses the same locks.

          For example, the TRansfer method calls the getTotalBalance method, which also locks the bankLock object, which now has a hold count of 2. When the getTotalBalance method exits, the hold count is back to 1. When the transfer method exits, the hold count is 0, and the thread relinquishes the lock.

          In general, you will want to protect blocks of code that require multiple operations to update or inspect a data structure. You are then assured that these operations run to completion before another thread can use the same object.

          5. Condition Objects
          Conditon Objects用來管理得了訪問權,卻實際并不能做有用功的線程。
          以銀行帳戶轉帳為例,轉帳時要確定轉出源的資金數不少于要轉出的金額。
          首先不能這樣簡單的寫代碼:
          if (bank.getBalance(from) <= amount)
          bank.transfer(from, to, amount);
          這種代碼完全有可能在if語句判斷完成后,transfer之前停滯,這樣在調用transfer的時候,可能帳戶當前的資金已經不是if語句判斷那個時候的數目了。
          也就是說,測試可行性和實際操作必須一起進行,之間不能有中斷。
          可以用一個lock把測試和操作綁定起來:
          public void transfer(int from, int to, int amount)
          {
          bankLock.lock();
          try
          {
          while (accounts[from] > amount)
          {
          // wait
          . . .
          }
          // transfer funds
          . . .
          }
          finally
          {
          bankLock.unlock();
          }
          }
          這樣還是有問題,帳戶資金不夠移出時,會困在while塊中等待資金撥入這個帳戶,但由于bankLock已經被鎖定,所以其他線程不能進行撥入操作,進入了死循環。這就是condition object產生的原因。
          一個lock對象可以有一個或多個相關的condition object,可以通過newCondition方法獲得一個條件對象,通常用實際條件命名每個條件對象,如
          class Bank
          {
          public Bank()
          {
          . . .
          sufficientFunds = bankLock.newCondition();
          }
          . . .
          private Condition sufficientFunds;
          }
          當transfer方法發現當前資金不夠時,調用
          sufficientFunds.await();
          這樣當前線程就會停滯,并解除lock。
          await方法調用后,線程進入對應Condition的等待區,直到另一個線程調用同一Condition的signalAll方法才會解除block狀態,并等待再次被線程管理器激活。
          如果一個線程調用了condition.await方法,卻沒有其他線程調用condition.signalAll,這個線程就進入了deadlock情況。如果所有其他的線程都進入了等待區,而最后一個線程也調用了condition.await,那么整個程序就掛起了。
          因此最好的調用signalAll的時機是在每次對象的狀態被改變,而這個改變有可能使得等待區的線程有進展的時候。如Bank中每次成功轉帳之后。
          另一個方法,signal,僅僅從等待區中隨機選擇一個進程并釋放。
          注意:線程只能在獲得了lock權以后才能調用condition的await, signal, 和signalAll。

          posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2.28 Java notes - Synchronization

          Posted on 2007-04-22 20:25 ZelluX 閱讀(332) 評論(0)  編輯  收藏 所屬分類: OOP
          2007-02-28 16:34:52
          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 江口县| 南京市| 彩票| 商都县| 乌拉特中旗| 东宁县| 新泰市| 五寨县| 门源| 磐安县| 长春市| 黄浦区| 富宁县| 广南县| 清镇市| 天门市| 枣阳市| 武城县| 临桂县| 阳谷县| 河津市| 南郑县| 烟台市| 黔南| 崇阳县| 阿鲁科尔沁旗| 龙井市| 巴马| 西乌珠穆沁旗| 敦煌市| 京山县| 旬邑县| 多伦县| 淮南市| 上林县| 平武县| 噶尔县| 富平县| 苍溪县| 佛坪县| 富源县|