【问题标题】:thread-safe collection for store and forward用于存储和转发的线程安全集合
【发布时间】:2017-01-28 05:40:45
【问题描述】:
这是我们必须开发的情况。
我们会有一群 ids 被一个作家连续插入到一个集合中。
目的是提醒客户有关这些特定 ID 的信息。
为此,调度线程将遍历此集合,整理 ID,然后将集合“重置”为空。
我打算为此使用 ConcurrentLinkedQueue。
虽然这会使它成为线程安全的;但有可能“重置”清除一些尚未收到警报的 id。
解决此问题的最佳方法是什么?
【问题讨论】:
标签:
java
collections
concurrency
【解决方案1】:
您的整理器线程应在处理队列时从队列中删除每个条目。如果您这样做,则无需重置队列,并且不会出现丢失通知的问题。
(如果这对您没有意义,很可能是您没有清楚解释的内容。尝试添加一些示例代码...)
【解决方案2】:
“重置”清除某些 id 的可能性只是问题所在,因此您可以做的是:
在调度线程中,
首先获取该特定队列中存在的 当前 id 的大小/数量
局部变量“size”中的时间,因为它会随着新元素的插入而改变。
然后迭代 ConcurrentLinkedQueue 直到 size,
同时迭代从 ConcurrentLinkedQueue 中删除/轮询元素以收集 id。
这样你就不需要重置 ConcurrentLinkedQueue。
【解决方案3】:
你可以保持这个越简单,出错的可能性就越小。
我会创建一个容器来管理您的 id 集合,只公开您需要的两个操作。
您的写入线程需要将条目添加到集合中,而您的调度线程需要批量提取它们。读取时复制策略只需要几行代码:
import java.util.ArrayList;
import java.util.List;
public class IdList<T> {
private ArrayList<T> entries = new ArrayList<>();
/**
* Add a notification ID to the collection.
*/
public synchronized void add(T entry) {
entries.add(entry);
}
/**
* Remove the next batch of notification IDs from the collection.
*/
public synchronized List<T> drain() {
ArrayList<T> current = entries;
entries = new ArrayList<>();
return current;
}
}