PpLK: |Practical Java| Chapter 5 Multithreading

|Practical Java| Chapter 5   Multithreading
for ease and speed in doing a thing do not give the work lasting solidity or
exactress of beauty!.  ----Plutarch, life of Pericles
要進行多線程編程, 首先該好好理解併發編程原理(concurrent programming).
("Instance 函數或者變量 " --- 指的是類的成員)
46>   面對 Instance 函數, synchronized鎖定的是對象而非函數或代碼.
         關鍵字 synchronized 可用作函數的修飾符(Modifier), 亦可以用作函數的
         語句. 應該注意到這裏的xynchronized 並不是平常認爲的互拆器(mutex)
         或者關鍵區 (critical section).
         對於 Instance 方法, 關鍵詞 synchronized 其實並不鎖定函數或代碼, 她鎖
         定的是對象, Remember: 每個對象只有一個lock (機鎖)與之相關聯.
         當 synchronized 被當作函數修飾符的時候, 她所取得的lock 將被交給函數
         調用者(某對象), 如果synchronized 用於 Object reference, 則取得的 lock 將被
         交給該reference 所指的對象.
         對於同一個對象進行同步控制意味着: [調用函數] 的線程將會取得對象的
         lock. 持有 [對象A 的lock] 意味着另一個通過 synchronized 函數或synchronized
         語句來申請 [對象A的lock]的線程, 在該 lock 被釋放之前將無法獲得滿足.
          
         synchronized 方法或 synchronized 區段內的代碼在同一時刻下可由多個線程
         執行 ----- 只要是對不同的對象調用該函數.
Ex:
 class Foo extends Thread{
        private int val;
        public Foo(int v){val = v;}
        public synchronized void printVal(int v){
         while(true){System.out.println(v); }
 }
 public void run(){printVal(val); }
        }
        class Bar extends Thread{
         private Foo sameFoo;
         public Bar(Foo f){ sameFoo = f; }
         public void run(){sameFoo.printVal(2); }
        }
        class PP{
 public static void main(String []args){
  Foo f1 = new Foo(1);
  f1.start();
  Bar b = new Bar(f1);
  b.start();
  Foo f2 = new Foo(3);
  f2.start();
 } 
        }
       在實例中, 首先create Foo 對象, 此線程進入一個無限循環因此Foo 對象的lock
       永遠得不到釋放; 然後create Bar對象, 此線程對同一個 Foo對象調用同一個
       synchronized  printVal()方法, 此時這個調用發生阻塞(block), 直到前一次執行結
       束. ----- 所以在輸出結果中是不可能出現 "2 " 的.
       PS: 同步機制(synchronized) 鎖定的是對象, 而不是函數或代碼. 函數或代碼區段
             被聲明爲synchronized 並非意味着她在同一時刻只能由一個線程執行.
             Java 不允許將construct Method 聲明爲synchronized, 原因是兩個線程併發調
                    用同一個construct Method時,她們各自操控的是同一個class 的兩個不同
                    實體的內存. 然而如果在construct 內含了彼此競爭共享資源的代碼, 則
                   必須同步控制那些資源以迴避衝突.

47>  弄清楚 synchronized statics 函數與 synchronized instance函數間的差異
        
        同步控制中的 instance函數 / static 函數 / objects / class literals
               情況下得到的 locks不同, 因此在決定互斥 (mutual exclusion)行爲時一定
               要小心謹慎.
48>  以 [private 數據 + 相應的訪問函數(accessor) 替換 [public/protected數據]
 
       使用synchronized 函數編碼, 目的在於使數據免遭混亂之災. 爲了適當保護數據,
       你必須確保正確的聲明和訪問她們. 這一點很重要.
       要想完全保護 synchronized 函數中的數據, 必須令這些數據成爲class 的private
       成員. 這是唯一可行的辦法.

50>   訪問共享變量時請使用 synchronized 或 volatile
 
51>   在單一操作(single Operation) 中鎖定所有用到的對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章