簡體   English   中英

我如何遍歷可能由另一個線程添加到的列表

[英]How do I iterate over a list that could be added to by another thread

我有一個列表,可以對其進行迭代並對其執行一些操作。 可以執行的操作之一可能導致工作傳遞給另一個線程,這可能會在我仍在第一個線程中對其進行迭代時將更多元素添加到列表中。

有沒有辦法讓我迭代列表,使迭代器包括來自另一個線程的添加項?

這是一些偽Java

Class1{

   List multiThreadList = getMyList(); //points to list in Class2
   for(Element element:multiThreadList)
      //perform some actions, these actions may results in another thread being called
      //which will cause addToMyList() to be called while I'm still iterating over it
      //I want to keep iterating if an element gets added on the other thread
}
Class2{
   List originalList = new ArrayList();

   public getMyList()
     return originalList;

   void addToMyList(Element element)
     originalList.add(element);
}

您確定List是您需要的那種收藏嗎?

我將使用BlockingQueue,並在一個線程中從BlockingQueue中刪除元素,然后添加另一個。 這樣,您將不需要任何其他的並發控制。

BlockingQueue<String> bounded   = new LinkedBlockingQueue<String>();

bounded.put("Value");

String value = bounded.take();

您的偽代碼成為

Class1{

   BlockingQueue queue = getMyList();
   Object element = queue.poll(0, TimeUnit.SECONDS);
   while(element != null) {
      //perform some actions, these actions may results in another thread being called
      //which will cause addToMyList() to be called while I'm still iterating over it
      //I want to keep iterating if an element gets added on the other thread  
      element = queue.poll(0, TimeUnit.SECONDS);
   }
}
Class2{
   BlockingQueue originalList = new LinkedBlockingQueue();

   public BlockingQueue getMyList()
     return originalList;

   void addToMyList(Element element)
     originalList.put(element);
}

但是有一件事,您需要了解,當前形式的此任務會給您帶來不一致的結果。 由於您不控制另一個線程,因此迭代器可能會在添加新元素之前完成,並且在迭代時會丟失它,具體取決於系統狀態,您可能會錯過從零到所有新元素的情況。 因此,您需要在完成迭代之前加入所有創建的線程,或者更改方法。

您將必須使用某種類型的並發控制機制,例如互斥鎖,信號燈或監視器。 這些會創建代碼的“關鍵部分”,一次僅允許一個線程對其進行訪問。

不幸的是,如果不以某種方式鎖定代碼並將其一部分串行化,就無法解決該問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM