用于获取大小和删除元素模式的 Java 线程安全集合

标签 java multithreading collections concurrency

我有一个在多个线程之间共享的字符串列表。每个线程必须:

  1. 访问列表(例如通过 getter 方法);
  2. 获取列表的大小;
  3. 选择一个介于 0 和 list.size() 之间的随机数 n;
  4. 从列表中提取偏移量为 n 的元素;
  5. 从列表中删除提取的元素;
  6. “保存”列表,以便其他线程始终查看更新的列表

由于存在对可变共享对象(列表)的并发访问,因此我需要以线程安全的方式进行编码。每个线程都必须将列表大小减一,因此每个其他线程访问都必须看到更短的列表。我的目标是避免一个线程可以看到另一个线程看到的相同列表,因为这样就有可能提取两次相同的元素。

实现这一目标的最佳方法是什么?我正在考虑 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/

相关文章:

collections - VecDeque 环形缓冲区在内部是如何工作的?

c# - LINQ .Any VS .Exists - 有什么区别?

java - 在批处理脚本中的 for 循环之后不打印任何内容

java - 如何在 Play Framework 2.2 中自定义 unmanagedResourceDirectories 和 exceptFilter?

java - 堆是否被多个线程共享?

java - 如何限制用作工厂的 TestNG dataprovider 方法上的线程

java - 如何在 Java 中对 MongoDB 查询结果进行排序?

java - 数字格式异常 :null

java - Thread.sleep() 保证等待吗?

java - 如果我的 map 需要小而不是快,我应该使用 Map<K,V> 的哪个实现?