同步的变量集合

时间:2016-12-29 21:22:10

标签: java synchronization

我想要具有线程安全的同步集合(列表或集合)。我的集合将包含Variable类的对象,其中包含name,value等文件。现在假设两个线程想要修改该列表中的对象(添加新的或删除现有的对象)。这是最好的解决方案吗?我在stackoverflow上找到了这样的smth。

List<Variable> varList = Collections.synchronizedList(new ArrayList<Variable>());

void processList(List<Variable> varList, String name)
{
    synchronized(varList) {
        varList.stream().filter(o -> o.getName().equals(name)).findFirst().ifPresent(o -> o.setValue(100));
    // or
    varList.remove(0);
    // or
    varList.add(new Variable());
    }
}

它会没有任何问题吗?或者有更好的解决方案吗?

2 个答案:

答案 0 :(得分:2)

最佳解决方案取决于用例。如果您需要一个有序的randomacces Collection,那么有3个选项。

1)您描述的那个(Synchronized List)。它将执行与底层Collection类型一样快的速度,使用drawBack将整个Collection锁定在Thread访问上。

除了Iterator实现默认情况下不是Threadsafe,因此需要额外的threadSafty度量。 (itetator通常用于forEach, clear和其他默认(java 8)实现)。

2) CopyOnWriteArrayList。这是JDK中唯一的ThreadSafe(包括具有快照功能的迭代器)randomAcces List。

缺点是它在添加/删除数据时复制数据。对于较小的集合,这可能不是问题,尽管基本规则是,当有更多的“读取”时,它是最好的解决方案。行动而非写作#39;动作。

3) Vector。这对于阅读&#39;而言有点慢。与CopyOnWriteList相对应的动作,尽管它的“写入”#39;机制不需要制作支持数据的副本。

这个问题的一个缺点是Iterator也不是ThreadSafe。与同步列表的区别在于,当有更多的线程访问集合时,它将比SynchronizedList执行得更好。



Sumarry:

Synchronized List

  • 访问线程数少,性能快。
  • 迭代器不是线程安全的

CopyOnWriteArrayList

  • 快速阅读&#39;&#39;操作
  • 将支持数据复制到&#39;写&#39;动作(可能是较大集合的问题)
  • Iterator是线程安全的(使用快照功能)

Vector

  • 与大量访问线程相比,性能更快(与同步列表相比)。
  • 迭代器不是线程安全的

答案 1 :(得分:1)

我会做得更简单。您只需要在同步块内的列表上进行所有修改,使用与锁相同的列表对象。

例如,假设您有列表

List<Variable> varList;

已经填充了Variable对象。现在,每次要在代码中访问或修改此List时,必须使用varList上的synchronized块锁定包含这段代码,如下所示:

    synchronized(varList) {
        // here you access, add, delete, or modify the List
        // for example:
        if(varList.get(1) == 3) {
            varList.remove(1);
            varList.add(new Variable());
        }
    }

为此,您必须确保两个线程正在使用相同 varList,这是,varList是两个线程的共享变量(例如字段或静态变量) 。您还可以使用任何其他新对象作为锁,但始终确保它是两个线程的公共对象(不是两个具有相同名称的变量引用内存中的不同对象)。 但我更喜欢使用列表本身作为锁,所以它使代码更清晰,我知道在该块中我正在修改该列表。