2015-12-21 16 views
1

我很茫然。我有一個BlockingDeque項目插入隊列後,BlockingDeque不會取消阻止

private class Consumer extends Thread { 

    @Override 
    public void run() { 
     try { 
      while (!Thread.currentThread().isInterrupted()) { 
       if (connection.isReady()) { 
        final Item item = queue.takeFirst(); 
        try { 
         ListenableFuture<Result> listenableFuture = connection.submitItem(item); 
         Futures.addCallback(listenableFuture, new FutureCallBackImpl<Result>(item)); 
        } catch (RejectedExecutionException e) { 
         LOGGER.debug("Slow down submission of tasks we have a queue full in connection"); 
         queue.addFirst(item); 

        } 
       } 
      } 
     } catch (InterruptedException e) { 
      LOGGER.debug("Interrupted. I will not propagate up because I own this thread"); 

     } 
    } 
} 

此代碼通常阻止在queue.takeFirst()當沒有項目在隊列中。但是,一旦按預期添加項目,它不會解除阻止。在調試過程中,我可以看到queue中的項目以及當我停止Tomcat時序列化queue。在開始之後,我將隊列反序列化,然後queue.takeFirst()檢索該項目(與之前未檢索到的項目相同)並提交。

有沒有人有任何想法?

編輯

要強調我的觀點多一點。如果我將queue.takeFirst()更改爲queue.pollFirst()並略微調整代碼以忽略產生nullitems的代碼,則代碼將按預期工作。

+1

我可以想像,(i)您沒有添加到隊列或(ii)你是不是從同一隊列中取出或(iii)您實際上正在從隊列中取出,但認爲您不是或(iv)所需的代碼永遠不會執行...... – assylias

+0

正如我在編輯中所說的,如果我將代碼更改爲pollFirst有用。我相信(i),(ii)不適用。對於(iii)調試器應停在我放入try的斷點處。 (iv)如果我停止並通過序列化/反序列化來啓動代碼,則代碼被執行我解釋了 – idipous

+1

沒有一段代碼來重現您的問題,我們只能猜測......您應該嘗試創建一個[mcve] (http://stackoverflow.com/help/mcve) – assylias

回答

0

也許你的代碼不輸入if,因爲connection.isReady()返回false

檢查它是否確實停止等待隊列中的第一項。

+0

調試時,我看到queue.takeFirst()中的線程塊。此外,爲什麼pollFirst()在這種情況下正常工作? – idipous

+0

雖然您在調試中的takeFirst上被阻止,但請檢查隊列的大小 –

+0

我擁有且大小隨着我提交項目而增加。我甚至可以看到隊列中的項目,當我停止tomcat時,我會看到它們序列化。同樣,一旦我再次啓動tomcat並反序列化隊列,它們實際上是通過相同的代碼發送的。 – idipous

0

所以讓我來解釋爲什麼當項目被添加到隊列中下一次這段代碼將無法正常工作(即後離隊第一的所有元素)

當隊列爲空的第一次,調用此代碼final Item item = queue.takeFirst();將拋出InterruptedException,它在while循環外被代碼捕獲,所以代碼將永遠不會再返回到while循環。在while循環中放置第一個try塊將解決第一個問題。

其次,它需要在catch塊內部調用Thread.currentThread().interrupted()來通過下一次的條件,以便爲將來的元素添加到隊列中準備好讀取。事實上,我不明白撥打這行代碼while (!Thread.currentThread().isInterrupted())的原因。

目前我寫BlockingDeque(WIP)有趣的博客,很快你就會在我的博客找到更多的信息http://singletonjava.blogspot.com

+0

pollFirst()將工作的原因是它永遠不會拋出任何InterruptedException,並且代碼永遠不會從while循環中退出。 –

+0

感謝您的輸入。到被拋出的異常拋出時,我真的打算離開while循環。另外我沒有在catch中設置Thread.currentThread().interrupt();'。我發現了這個錯誤,我會更新答案以便解釋它,但是我打算這樣做,因爲我需要提出解決方案 – idipous

+0

也許,您應該嘗試更詳細地解釋您打算用這段代碼來實現,這將幫助其他人更符合你的想法而不是假設。 –