2015-10-05 45 views
2

我有一個使用ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));運行的以下可運行任務這確保了隊列中只有一個等待任務。Future.cancel()方法中的問題

protected void waitAndSweep(final String symbol) { 
    try { 

     runnable = new Runnable() { 
      @Override 
      public void run() { 
      try { 
      // long sweepTime = symbolInfo.getSweepTime(symbol); 
       // long timeSinceLastSweep = System.currentTimeMillis() - lastSliceSentTime; 
       boolean sliceDone = Quant.equals(wave.getCommitedQuantity() % getSliceQuantity(),0); 
       if(sliceDone){ 
       long timeSinceLastSliceQtySent = lastSliceSentTime == 0 ? getInterval() : System.currentTimeMillis() - lastSliceSentTime; 
       long waitTime = timeSinceLastSliceQtySent >= getInterval() ? 0 : getInterval() - timeSinceLastSliceQtySent; 
       logTradeEvent("waitAndSweep", symbol, "waittime: " + waitTime); 
       if (waitTime > 0){ 
        Thread.sleep(waitTime); 
       } 
       } 

       callSweep(symbol); 
      } catch(InterruptedException ie){ 
       ie.printStackTrace(); 
      } 
      catch (Exception e) { 
       logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol, 
        "Exception caught...", e); 
      }    
      } 
     }; 

     self = threadPoolExecutor.submit(runnable); 
    }catch(RejectedExecutionException re){ 
     /* this exception will be thrown when wait and sweep is called more than twice. 
     * threadPoolExecutor can have one running task and one waiting task. 
     * */ 
     System.out.print(re); 
     }catch (Exception e) { 
     logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol, 
      "Exception caught...", e); 
    } 
    } 

考慮來電答:

private void callerA(){ 
waitandsweep(); 
waitandsweep();} 

這craetes兩個工作一會運行,在隊列中另一個等待。

考慮callerB:

private void callerB(){ 
self.cancel(true); 
waitandsweep();} 

期待callerB取消由A. 調用的所有任務,其實這是不會發生..任務通過者B調用是越來越拒絕,因爲已經有一個任務在等待隊列。你能否說出爲什麼會發生這種行爲?

編輯1:如何取消執行程序的運行任務?

回答

3

問題是,Future.cancel(boolean)不會從隊列中刪除任務。該任務將不會被執行,一旦將由Executor拉但在那之前它仍在隊列

嘗試使用threadPoolExecutor.purge();​​之後它會嘗試刪除已取消的任務

取消正在運行的任務是不是那麼容易,你可以嘗試以下: 致電cancel(true);它將設置Thread.interrupted()true。現在在你的任務中檢查一些有價值的步驟,所以你可以決定跳過你的任務的下一步

+0

什麼是從隊列中刪除任務的方式。並通過取消方法終止正在運行的任務? – user5367186

+0

@ user5367186你實際上不能「終止」一項任務。您需要檢查「中斷」/「isCanceled」 - 任務中的值 – JohnnyAW

+0

如何中斷來自callerB的thread.sleep? – user5367186