2013-08-22 29 views
1

我開始對一個項目隊列進行長時間運行的過程,並且某個項目要麼計劃要處理,要麼正在處理中,但我想禁止其他一些操作。我的代碼基本上是這樣的:使用兩個單獨的Java併發結構重新排序

​​

將這項工作我期待,或是否有可能在突出顯示的代碼塊的方式上面重新排序?你能指點我的任何相關規格嗎?

編輯:

@ Banthar樂於助人的評論使我的java.util.concurrent package documentation,回答明確我的問題:

所有類的方法java.util.concurrent及其子包這些保障擴展到更高級別的同步。特別是:

  • 將對象放入任何併發收集之前操作在一個線程發生-之前該元素的從收集在另一個線程訪問或移除後續動作。

回答

1

將這項工作我期待,或是否有可能選擇這兩種方式突出顯示上述項目進行重新排序?你能指點我的任何相關規格嗎?

簡短的回答是,因爲兩個集合都是併發類,所以active.add(...)將不會在pending.remove()之後發生。

  • pending.peek();pending.remove();訪問volatile字段head

    private transient volatile Node<E> head = new Node<E>(null); 
    
  • active.add(nextItem);訪問內部鎖定volatile領域:

    compareAndSetState(0, acquires)) { 
    

因爲無論你的收藏是併發類,它們都具有內部鎖或volatile變量,這樣的方法的調用已讀/編寫確保「發生之前」保證的內存屏障。這確保操作不能因爲Java Memory Model而被重新排序。

但是,這並不意味着您的邏輯是正確的,或者當您查看其他線程如何使用這兩個集合時,沒有競爭條件。此外,這些調用不是原子的,所以你可以有3個線程:

  1. t1 - Item nextItem = pending.peek();
  2. t2 - Item nextItem = pending.peek();
  3. t1 - 有效。添加(nextItem);
  4. t3 - 將nextItem從活動中移除並處理它或某物
  5. t2 - active.add(nextItem);
  6. T3 - 從活動中刪除nextItem,並再次對其進行處理
+0

這是我的想法,謝謝。沒有其他線程正在訪問這些集合;這是一個單線程任務(沒有't2'或't3')。你有沒有可以參考的參考資料? –

+1

@BrandonMintern http://stackoverflow.com/questions/1770166/is-concurrenthashmap-get-guaranteed-to-see-a-previous-concurrenthashmap-put –

+1

這裏是JMM信息@BrandonMintern。 http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#reordering – Gray

相關問題