![](/img/trans.png)
[英]Why the ArrayBlockingQueue is called a bounded queue while a LinkedBlockingQueue is called an unbounded blocking queue?
[英]Java ArrayBlockingQueue blocking until the queue has something in it
我有許多不同的套接字連接到我的代碼,每個套接字都在獨立線程上偵聽。 在將對象傳遞到這些套接字中的任何一個之前,時間可能會過去。 所以我有一個基本上永遠運行的 while(running) 循環。
然后為了同步所有不同的線程,我有一個 ArrayBlockingQueue。 每當套接字/線程組合接收到一個對象時,我就會將該對象添加到 ArrayBlockingQueue(因為它會自動為我同步)。 然后在 while(running) 代碼中,我刪除對象並處理它。
問題是處理器在那個 while(running) 循環中變得瘋狂......理想情況下,我想阻止開始處理所有對象,直到 ArrayBlockingQueue 實際上有一些東西要處理,希望處理器不會繼續運行。
你知道這是否可能?
這是我當前的代碼,它導致處理器旋轉並浪費周期......
@Override
public void run()
{
while(running)
{
while(messageQueue.size() > 0)
{
Object o = messageQueue.remove();
}
}
}
這是我想要的...
@Override
public void run()
{
while(running)
{
messageQueue.BlockUntilSomethingInHere();
while(messageQueue.size() > 0)
{
Object o = messageQueue.remove();
}
}
}
請注意,在執行messageQueue.remove()
之前檢查messageQueue.size() > 0
被稱為check-then-act反模式。 如果您有多個線程移除元素,則有可能條件在檢查和后續操作之間發生變化,從而導致異常。
只需使用take()
而不是remove()
:
while(running) try {
Object o = messageQueue.take();
// ...
} catch(InterruptedException ex) {
// (running) will be checked before the next loop iteration
}
take()
將等待元素變為可用。 要在隊列為空時結束此循環,您必須將running
設置為false
並中斷線程。 如果無法中斷,您可以使用定時等待:
while(running) try {
Object o = messageQueue.poll(1, TimeUnit.SECOND);
if(o != null) {
// ...
}
}
catch(InterruptedException ex) {
// (running) will be checked before the next loop iteration
}
然后,可能需要一秒鍾,直到等待空隊列的線程對running
設置為false
做出反應(請注意將running
聲明為volatile
)。 可以更改超時時間,以權衡響應能力和 CPU 消耗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.