2

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

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

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

实现这一目标的最佳方法是什么?我在考虑 CopyOnWriteArrayList 但我不确定它的行为是否符合我的需要。

谢谢

4

2 回答 2

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;
}

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

  • 创建列表
  • 随机播放(引入随机性)
  • 使用该列表填充 BlockingQueue(例如LinkedBlockingQueue
  • 让您的线程从队列中获取项目(线程安全原子操作 => 不需要额外的同步)
于 2013-01-08T07:09:01.887 回答
0

我看不出有什么理由不能将上述逻辑序列放在同步块中,或者在上述逻辑序列期间使用信号量/互斥锁来独占访问列表。

于 2013-01-08T07:09:10.243 回答