*
          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
          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 永嘉县| 衢州市| 丰镇市| 沙雅县| 枣庄市| 仁寿县| 民丰县| 资中县| 长子县| 华坪县| 资溪县| 鸡泽县| 忻城县| 镇巴县| 深水埗区| 龙山县| 金华市| 张家界市| 民丰县| 葵青区| 读书| 二手房| 手游| 十堰市| 盐源县| 兴业县| 永州市| 蛟河市| 根河市| 伊宁县| 青川县| 千阳县| 辉县市| 大城县| 施秉县| 侯马市| 谷城县| 卓资县| 梅河口市| 阆中市| 安岳县|