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