我有一个在多个线程之间共享的字符串列表。每个线程必须:
- 访问列表(例如通过 getter 方法);
- 获取列表的大小;
- 选择一个介于 0 和 list.size() 之间的随机数 n;
- 从列表中提取偏移量为 n 的元素;
- 从列表中删除提取的元素;
- “保存”列表,以便其他线程始终查看更新的列表
由于存在对可变共享对象(列表)的并发访问,因此我需要以线程安全的方式进行编码。每个线程都必须将列表大小减一,因此每个其他线程访问都必须看到更短的列表。我的目标是避免一个线程可以看到另一个线程看到的相同列表,因为这样就有可能提取两次相同的元素。
实现这一目标的最佳方法是什么?我正在考虑 CopyOnWriteArrayList 但我不确定它的行为是否符合我的需要。
谢谢
最佳答案
问题是操作 1 到 6 需要是原子操作,使用 CopyOnWriteArrayList 无法解决这个问题。
一种解决方案是简单地同步整个操作:
private final List<String> list = new ArrayList<String> ();
public String getNextItem() {
synchronized(list) {
//get the string adn remove it from the list
}
return next;
}
或者,您可以检查您的算法并执行以下操作:
- 创建列表
- 随机播放(引入随机性)
- 使用该列表填充 BlockingQueue(例如 LinkedBlockingQueue )
- 有你的话题take items从队列中(线程安全原子操作 => 不需要额外的同步)
关于用于获取大小和删除元素模式的 Java 线程安全集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14209844/