很多读者,一位作家:我需要同步吗?

时间:2010-02-22 16:40:46

标签: java synchronized

当需要访问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();
  }
}

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

Janning

4 个答案:

答案 0 :(得分:5)

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

  • computeList不依赖于myList
  • 的当前状态
  • 在分配后,您不会更改列表的内容(Collections.unmodifiableList(computeList())是表达此条件的更好方式)。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

我宁愿做隐含的副本

public class ListContainer {

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

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

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

HTH