2014-03-30 79 views
0

我一直在一個有兩個線程的小項目。 一個生成內容並將其放入隊列(在靜態上下文中)。 另一個線程運行並等待隊列中的內容執行某些操作。雖然循環線程似乎沒有運行

的問題:

雖然第二個線程在等待的東西放置在隊列中,它似乎沒有運行,我會盡量表現出這一點。

我只是好奇是這裏發生了什麼。

_slices是一個隊列:Queue<E> _slices = new LinkedList<E>();

線程2 run()

while (true) { 
    if (!Main._slices.isEmpty()) { 
      System.out.println("Something in the Queue!"); 
     } else if (Main.doneQueuing) { 
      break; 
     } 
} 

此代碼以上不會一旦元件被添加到隊列中做任何事情。現在


,此代碼的工作:

while (true) { 
    System.out.println("As long as a process is done here it works"); 
    if (!Main._slices.isEmpty()) { 
      System.out.println("Something in the Queue!"); 
     } else if (Main.doneQueuing) { 
      break; 
     } 
} 
+0

這意味着隊列沒有被填充。檢查填充隊列的代碼,並確保兩個隊列引用都指向同一個隊列實例。 –

+0

'_slices'的類型是什麼? – nosid

+0

@AniketThakur隊列與此無關,正如我上面所說的,有一個案例可行。 – MichaelMitchell

回答

1

基於所提供的信息,我只能猜測。我想你的代碼如下所示。數據結構_slices在線程之間共享,有一個方法push,它將一個元素添加到共享數據結構並在一個線程中執行。並且有一個方法輪詢,它檢查數據結構是否爲空,並在另一個線程中執行。

class Foo { 
    Queue<String> _slices = new ArrayDeque<>(); 
    void push(String element) { 
     _slices.add(element); 
    } 
    void poll() { 
     while (!_slices.empty()) { 
      // ... 
     } 
    } 
} 

在上述示例中,有一種所謂的數據爭。這意味着Java編程語言不能保證執行順序一致。還有一些保證。但是,它們相當複雜。

爲了避免數據競爭,您應該使用支持併發的數據結構,例如, ConcurrentLinkedQueueLinkedBlockingQueue。或者你應該在代碼中使用一些同步機制,例如同步塊。

+0

但是爲什麼依賴線程在if語句之前識別出添加了一個元素(大小不再是0),如果有一個進程(如println)。 – MichaelMitchell

+1

@MichaelMitchell:因爲_println_中還有一些同步。這不會刪除_data race_。但是,它會改變_race condition_的概率。 – nosid

+0

我認爲這是有點超過我目前的理解。我會隨你的建議去做。感謝您的時間。 – MichaelMitchell