2015-02-10 189 views
0

我想知道我對下面的代碼示例是正確的。 我在java中有兩個線程。 Thread_W and Thread_R 兩者都可以訪問Queue<String> queueJava多線程寫入和讀取

在Thread_W中有一個名爲put的方法。

private void put(String email){ 
queue.offer(email); 
} 

並且在Thread_R中有一個名爲get AND的方法,它在Thread_R啓動時被調用一次。

public void get(){ 
while(true) 
{ 
    if(!queue.isEmpty()) 
    { 
     String to = queue.poll(); 
     //thread will consume some time here ...may be 5-10 seconds. 
    } 
} 
} 

所以在Thread_W方法put將稱爲更有效地通過在Thread_W.may甲其他方法是在while循環。

如果我在我的Java項目中使用此代碼,Thread_R會丟失放入隊列的任何電子郵件嗎?

P.S.我真的需要一個緩衝區

+3

看看java的併發性。你需要一個線程安全的隊列。 – vikingsteve 2015-02-10 19:25:48

+0

爲什麼閱讀主題「失去任何電子郵件」? – Zhedar 2015-02-10 19:25:56

+0

您應該使用鎖定來防止同時發生讀寫。它的要點是寫入過程正在寫入,所以它鎖定隊列。讀取進程嘗試訪問隊列,但必須等待寫入完成.. – 2015-02-10 19:26:26

回答

0

您應該使用Blocking Queue接口的實現,因爲那些接口是線程安全的。

該界面提供了方法put()take(),這些方法會一直執行,直到它們被執行。這樣,如果隊列已滿,讀取線程不會佔用大量CPU週期,寫入線程也不會寫入。
您當前的忙等待

while(true) 
{ 
    if(!queue.isEmpty()) 
    { 
     //... 
    } 
} 

是不是很有效。最好使用阻塞方法調用,所以如果隊列爲空(或滿),則不需要檢查。
如果您的寫入線程比讀取線程的速度快put() wait的for space to become available,您也無法溢出隊列的緩衝區。

請記住,您可以隨時手動爲隊列預留更大的緩衝區,方法是事先在其中設置capicitiy,例如, ArrayBlockingQueue(int capacity)

+0

但我需要一個大的緩衝區size.unlimited。因爲寫入緩衝區會很快發生。只有讀取速度會很慢 – 2015-02-10 19:34:37

+0

'put()'會阻塞寫入線程,直到緩衝區中有空間。根據文檔:'將指定的元素插入到該隊列中,等待空間變得可用。'更大的緩衝區不是最好的解決方案。 – Zhedar 2015-02-10 19:36:20

+0

put()將阻止寫入線程....這是問題.... 我需要一個緩衝區解決方案...就像YouTube加載所有視頻然後播放 – 2015-02-10 19:38:41

0

如果你想使用一個無限制的併發隊列,我建議看看Deque的線程安全實現,例如LinkedBlockingDequeLinkedBlockingDeque可以是無限的,如果隊列爲空,則take()將阻塞調用線程。如果使用java.util.concurent包中的類,則不必擔心同步。