用于get-size-and-delete-element模式的Java线程安全集合

pas*_*nte 2 java collections concurrency multithreading

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

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

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

这是实现这一目标的最佳方法?我正在考虑CopyOnWriteArrayList,但我不确定它的行为就像我需要的那样.

谢谢

ass*_*ias 7

问题是操作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;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以查看您的算法并执行以下操作:

  • 创建列表
  • 洗牌(引入随机性)
  • 使用该列表填充BlockingQueue(例如LinkedBlockingQueue)
  • 让你的线程从队列中获取项目(线程安全原子操作=>不需要额外的同步)