4

当许多线程访问 get 方法而只有一个线程访问 setList 方法时,我需要同步吗?

public class ListContainer {
  private List<String> myList = new ArrayList<String();

  public List<String> get ( )
  {
    return new ArrayList<String>(myList);
  }

  public List<String> set ( )
  {
    this.myList = computeList();
  }
}

我不在乎读者是否获得旧数据,但数据应该是一致的。

詹宁

4

4 回答 4

5

如果满足以下条件,则不必同步(但必须声明myList为):volatile

  • computeList不依赖于当前状态myList
  • 分配后您不会更改列表的内容(Collections.unmodifiableList(computeList())是表达此条件的更好方法)
于 2010-02-22T16:52:16.803 回答
1

不,您不需要同步。没有任何并发​​修改(如果computeList()不依赖于myList)。

顺便说一句,你为什么要返回new ArrayList(myList)而不是简单地返回myList

于 2010-02-22T16:54:44.603 回答
0

computeList 是否依赖于 myList 无关紧要,只要对 myList 的内容只有读取权限,就不会出现同步问题。

如果没有对 myList 使用 volatile,那么即使严格设置已经替换了列表,get 也可能会返回旧的 myList。如果您不介意这种情况(它可能导致两个线程看到不同的值),那么您不需要 volatile。

于 2010-02-22T17:45:29.460 回答
0

我宁愿复制隐含的

public class ListContainer {

    private final List<String> myList = new CopyOnWriteArrayList<String>();

    public List<String> get (){
      return myList;
    }

    public List<String> set (){
       computeList();
    }
}

高温高压

于 2010-02-24T00:35:07.083 回答