Java多線程基礎(四)Java傳統線程同步通訊技術
Java多線程基礎(四)Java傳統線程同步通訊技術編寫代碼實現以下功能
子線程迴圈10次,接著主線程迴圈100次,接著又回到子線程迴圈10次,接著再回到主線程又迴圈100次,如此迴圈50次。
分析
1)子線程迴圈10次與主線程迴圈100次必須是互斥的執行,不能出現交叉,下面代碼中通過synchronized關鍵字實現此要求;
2)子線程與主線程必須交替出現,可以通過線程同步通訊技術實現,下面代碼中通過bShouldSub變數實現此要求;
其他需要注意的地方
1)其中business變數必須聲明為final類型,因為在匿名內部類和局部內部類中調用的局部變數必須是final的,這樣保證:
- 變數的一致性(編譯時間final變數會被複製一份作為局部內部類的變數);
- 並避免局部變數的生命週期與局部內部類的對象的生命週期不一致。
否則,
- 若該變數被傳入局部內部類之後,局部變數在外部類中被修改,則內部類中該變數的值與外部類中不一致,可能導致不可預知的情況發生;
- 或是導致局部變數生命週期隨著方法的結束而從棧中清除,局部內部類訪問一個已不存在的變數。
若是成員變數,則不需要是final的。
詳情可參考以下文章:
http://feiyeguohai.iteye.com/blog/1500108
http://blog.csdn.net/whuslei/article/details/6251020
2)內部類分為成員內部類、靜態內部類、局部內部類、匿名內部類四種,四者的生命週期及詳細使用方法請自行問Google或度娘。
代碼實現
package cn.king;public class TraditionalThreadCommunication { public static void main(String[] args) { // 必須聲明為final final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for(int i=1; i<=50; i++) { business.sub(i); } } } ).start(); for(int i=1; i<=50; i++) { business.main(i); } }}class Business { // 該變數用於線程間通訊 private boolean bShouldSub = true; public synchronized void sub(int i) { if(!bShouldSub) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=1; j<=10; j++) { System.out.println(sub thread sequence of + j + , loop of + i); } bShouldSub = false; this.notify(); } public synchronized void main(int i) { if(bShouldSub) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=1; j<=100; j++) { System.out.println(main thread sequence of + j + , loop of + i); } bShouldSub = true; this.notify(); }}