简体   繁体   English

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

[英]Many Readers, one writer: Do i need to synchronize this?

do i need to synchronize this, when many threads accessing the get Method and only one thread is accessing the setList method? 我需要同步这个,当许多线程访问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();
  }
}

I dont care if readers get old data, but the data should be consistent. 我不在乎读者是否获得旧数据,但数据应该是一致的。

Janning Janning

You don't have to synchronize (but you must declare myList as volatile ) if the following conditions are true: 如果满足以下条件,则不必同步(但必须将myList声明为volatile ):

  • computeList doesn't depend on the current state of myList computeList不依赖于myList的当前状态
  • You don't change content of the list after it was assigned ( Collections.unmodifiableList(computeList()) is the better way to express this condition) 分配后的列表内容不会更改( Collections.unmodifiableList(computeList())是表达此条件的更好方法)

No, you don't need there synchronization. 不,你不需要同步。 There are no any concurrent modifications (if computeList() doesnt depends on the myList ). 没有任何并发​​修改(如果computeList()不依赖于myList )。

btw, why are you returning new ArrayList(myList) instead of simply return myList ? new ArrayList(myList) ,为什么要返回new ArrayList(myList)而不是简单地返回myList

It does not matter whether computeList depends on myList or not, as long as there is only reading access to the content of myList no synchronisation problem can arise. 无论computeList是否依赖myList都没关系,只要对myList的内容只有读取权限就不会出现同步问题。

If not using volatile for myList then it might occur that get returns the old myList, even though strictly set has already replaced the list. 如果没有为myList使用volatile,那么可能会发生get返回旧的myList,即使严格设置已经替换了列表。 If you don't mind this situation (it could lead to two threads seeing different values), then you don't need volatile. 如果你不介意这种情况(它可能导致两个线程看到不同的值),那么你不需要volatile。

I would rather do the copy implicit by 我宁愿做隐含的副本

public class ListContainer {

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

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

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

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM