2013-05-13 77 views
1

最近我一直在重構我的項目,「ReentrantLock的」簡化的邏輯。

的總體思路是:的ReentrantLock - >的lockInterruptibly()不會檢查有時會中斷狀態?

1.「主」運行的線程在其自身的運行
2.如果一切正常,主線程會等待條件「NEXTSTEP」
3.當發生了什麼錯誤,方法「onCancel()」將/在另一個線程中調用,迫使主線程拋出InterruptionExcpetion,所以在關機會發生

一些測試後,它變成了我自己的方法:

doInterrupt(); 

從未按預期工作:強制主線程輸入「InterruptedException」子句並退出循環。

更新2:
我添加了一個「是間斷」調試消息到所有的輸出日誌行,如果原來的中斷狀態是「神不知鬼不覺」的一些之一清除...

UPDATE:
鎖定和狀況的方法:



    lock.lockInterruptibly(); 
    condition.await(); 

看起來有時不檢查中斷狀態? ....的Javadoc寫着:
 
    ...... 
    If the current thread: 
    has its interrupted status set on entry to this method; or 
    is interrupted while acquiring the lock, 
    then InterruptedException is thrown and the current thread's interrupted status is cleared. 
    ...... 

從日誌可能看到類似:


    [action] waiting for completion...: 1 [is-interrupted:false] 
    >> DEBUG ---> will begin next loop  [is-interrupted:false] 
    [action] reset for next iteration: 2 [is-interrupted:false] 
    [action] cancelling...     [is-interrupted:false] 
    >> DEBUG ---> will interrupt   [is-interrupted:false] 
    >> DEBUG ---> check.     [is-interrupted:true] 
    [action] waiting for completion...: 2 [is-interrupted:false] 
    >> DEBUG ---> will begin next loop  [is-interrupted:false] 
    [action] reset for next iteration: 3 [is-interrupted:false] 
    [action] waiting for completion...: 3 [is-interrupted:false] 
    >> DEBUG ---> will begin next loop  [is-interrupted:false] 
    [action] reset for next iteration: 4 [is-interrupted:false] 
    [action] waiting for completion...: 4 
    >> DEBUG ---> will begin next loop 
    [action] reset for next iteration: 5 
    [action] waiting for completion...: 5 
    >> DEBUG ---> will begin next loop 
    [action] reset for next iteration: 6 
    ...... and so on until i == max 
    [info] main process has reached a finish state. 

這基本上意味着中斷信號丟失或不可不知怎麼處理......

是有更好的方法嗎?或至少是我的代碼邏輯的修復?

任何多線程專家???

這裏是我的代碼:

public class SBCSTaskEngine extends GenericEngine<SBCSTask> implements XListener { 
    private final ReentrantLock  lock  = new ReentrantLock(); 
    private final Condition   nextStep = lock.newCondition(); 
    private volatile Thread   main  = null; 
    // something else ... 

    // it's a runnable "MAIN" 
    @Override 
    protected void run() { 
     try { 
      main = Thread.currentThread(); 
      // some setting up... x is between 1 ~ 10000 
      for (int i = 1; i <= max; i++) { 
       lock.lockInterruptibly(); 
       // some work ... 
       log("[action] waiting for completion...: " + i); 
       // a very long wait (could be REALLY fast if task went south) 
       nextStep.await(); 
       if (max == i) { 
        isNormalCompletion = true; 
       } else { 
        log("[action] reset for next iteration:" + (i+1)); 
        // some reset work... 
       } 
       lock.unlock(); 
      } // end of [for] loop 
     } catch (InterruptedException e) { 
      log("[event] process stopped by singal."); 
     } finally { 
      try { lock.unlock(); } catch (Throwable ignored) {} 
     } 
     log("[info] main process has reached a finish state."); 
    } 

    private void doInterrupt() { 
     log(">> DEBUG ---> will interrupt"); 
     if (main != null) 
      main.interrupt(); 
      log(">> DEBUG ---> check."); 
    } 

    /** 
    * implement: XListener(series) 
    * instruct main process to enter cancel sequence 
    * 
    * known-issue: duplicate call? sync on method? wait for risk evaluation 
    */ 
    @Override 
    public void onCancel() { 
     log("[action] cancelling..."); 
     doInterrupt(); 
    } 

    /** 
    * implement: XListener(series) 
    * proceed the main thread to next loop 
    * 
    * known-issue: signal might occur before all "memebers" could await on the condition (happen-before?), just take the chance for now... 
    */ 
    @Override 
    private void doNotifyNextStep() { 
     try { 
      lock.lockInterruptibly(); 
      log(">> DEBUG ---> will begin next loop"); 
      nextStep.signalAll(); 
     } catch (InterruptedException e) { 
      doInterrupt(); 
     } finally { 
      try { lock.unlock(); } catch (Throwable ignored) {} 
     } 
    } 
} // end of [SBCSTaskEngine] class 


更多信息:Java版本我用:

java version "1.6.0_26" 
Java(TM) SE Runtime Environment (build 1.6.0_26-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode) 
+0

嘗試使所有字段最終(鎖定,nextStep和主) – ZhekaKozlov 2013-05-13 09:48:30

+0

orionll <<爲什麼?你可以解釋嗎 ? ReentrantLock裏面的Sync實現不應該工作嗎? – Leemax 2013-05-13 10:02:49

+0

似乎有在你的代碼中的一些設計問題。請閱讀以下指導原則: https://www.securecoding.cert.org/confluence/display/java/VNA00-J.+Ensure+visibility+when+accessing+shared+primitive+variables 的https:// WWW 。+。+ + + + + + +方法+內+ + +循環 – ZhekaKozlov 2013-05-13 10:10:59

回答

0

經過仔細檢查「過程中使用的每一個方法()」,它原來有一個方法‘吞噬’的InterruptionExcept意外離子...

有了簡單地拋出了異常,整個代碼/類的工作作爲目前預計~~~

非常非常感謝誰在我的帖子評論說:「@hendalst」讓我修改所有可能的中斷泄漏...正如你所說的:「上面的代碼工作」,引起法根是註釋區域「//一些工作......」這是我沒有在這裏發表裏面...

和感謝「@orionll」對於關於編碼原理的建議

+0

很高興它的工作。爲了將來遇到類似問題的人的利益,請編輯此答案,詳細說明具體原因以及解決方法。 – pwrex 2013-05-14 03:58:28