2015-11-09
6:17 PM
在使用多執行緒我們常常需要使用到 synchronize 確保值的一致性
但是有一些情況很容易造成資料錯亂
這時我們就必須將某一些 Thread lock 住
直到確認其他 Thread 的前置工作完成了 才執行其他 Thread 的後續工作
以下就來介紹執行緒的 lock 該如何設計
本範例將以同一個 class 內的多個執行緒做個簡單示範
程式碼範例
// 宣告一個 final 的變數 將作為參數傳遞至各執行緒 private final Object locker = new Object(); // 宣告另一個變數 作為判斷是否需要 lock 執行緒 // 至於在各執行緒間的傳遞方式有很多種 在這裡就不多作介紹 private boolean commandLock = false; // Thread 1 while(true){ if( !isConnected() ){ lostConnection = true; break; } // 設定為 lock 狀態 commandLock = true; // Do something // 設定為 unlock 狀態 並喚醒上一個等待中的Thread // 注意此處的 synchronized 是確保同時間只有一個執行緒操作 locker 物件 commandLock = false; synchronized (locker) { locker.notify(); } } // Thread 2 public void reloadPage(){ commandLocker(); command( "Do reload" ); } // Locker private void commandLocker(){ // 檢查 lock 狀態 若為 lock 狀態則進行 wait 動作 // 直至 lock 狀態結束 synchronized (locker) { while(commandLock){ try { locker.wait(); } catch (InterruptedException e) { logger.error("Thread sleep error in command locker section."); } } } }
可能有人會看過在 while loop 中不使用 obj.wait(); 的作法
而是使用 Thread.sleep(millis); 的方式
但此方式容易消耗過多的效能進行不必要的 loop 執行
而且若 millis 沒有設定好 若同時有其他 Thread.sleep(); 的動作
很有因為時間差而可能造成 locker 永遠不會被解除的問題
但若單純使用空的 while 那效能的浪費是非常可怕的
因此還是使用 synchronized 加上 locker 物件的方式會較適當
各項資料連結
Java - Synchronized
No comments:
Post a Comment