2009-07-14 21 views
3

當隊列中沒有任何內容和調用take()時會發生什麼。 API表示該方法將等待,但這是否意味着CPU將在空閒/非空空閒時檢查空隊列,或者是否意味着該線程產生並將被中斷喚醒?如果是前者的情況,我可能想要查看隊列是否爲空,以及是否調用thread.yield()來放棄處理器時間。我的問題是我真的需要調用yield還是爲內部機制處理這個問題?java&線程:中斷的異常和如何正確使用BlockingQueue的take()方法

其次,什麼是中斷例外意味着什麼?如果我理解正確,這意味着如果線程A正在執行此方法並且正在等待輸入,並且另一個線程B調用了threadA.interrupt(),則線程A將捕獲中斷的異常,並且可能暫停執行,如果它很好的話。這是正確的思考方式嗎?

+1

文章上InterruptedException的:戈茨:http://www.ibm.com/developerworks/java/library/j-jtp05236 .html Kabutz:http://www.javaspecialists.co。za/archive/Issue056.html – McDowell 2009-07-14 08:32:12

+0

我建議提交2個問題而不是2個問題。否則,它使投票體面的答案更復雜一點 – 2009-07-14 16:57:46

回答

4

wait()調用不旋轉,它通常使用OS服務來等待事件/條件 - 這會將線程置於休眠狀態,直到條件/事件再次發出信號。等待時不使用處理器時間。

如果線程在wait()調用中被阻塞,並且另一個線程在該阻塞線程上調用interrupt(),通常會得到被中斷的異常,就像您所說的那樣。

+0

我怎麼知道等待事件/條件會把線程睡覺?換句話說,api並沒有說線程會進入睡眠狀態並被喚醒,所以我怎麼知道這個方法實際上會做什麼? – jbu 2009-07-14 08:47:44

+0

您可以查看Sun提供的源代碼。如果你正在使用另一個Java實現,我不知道。 – nos 2009-07-14 11:48:41

0

調用yield()被認爲是一個壞習慣,因爲它不能確保的好處 - 您可以調用它並且調度程序立即返回到您的線程,因爲它是無操作的。使用定時等待(例如,等待(1000))。

中斷的信號,你想從它的東西一個線程安全的方式 - 停止處理,醒來的東西作出反應,等

一般來說,這些事情都取決於你的具體方案。 Java具有一些關於併發性的優點,可以更適用於某種情況。

5

請注意,BlockingQueue是一個接口。所以接下來是依賴於實現。如果您查看(說)LinkedBlockingQueue的源代碼,take()的源代碼在RentrantLock上調用lockInterruptibly()。從doc此:

如果鎖不可用, 當前線程 線程調度目的,將被禁用,位於 休眠狀態,直到兩件事情 一個情況:

* The lock is acquired by the current thread; or 
* Some other thread interrupts the current thread, and interruption of 

鎖獲得支持。

我懷疑有一些wait()/notify()或類似的事情發生。它會旋轉CPU嗎?沒有(通過top或類似檢查)

Re。您的關於中斷的問題,Java專家通訊在interrupt()上有一個very interesting article和捕獲/處理InterruptedException

閱讀文章,但本質上,如果你捕獲異常,你reinterrupt:

try { 
     Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
     Thread.currentThread().interrupt(); // very important 
     break; 
     } 
相關問題