【问题标题】:Copying an element of a volatile ArrayList复制 volatile ArrayList 的元素
【发布时间】:2017-09-01 21:38:28
【问题描述】:

假设我有以下代码:

public class MyClass
{
    private volatile ArrayList<ArrayList<MyImmutableClass>> arraylist = new ArrayList<ArrayList<MyImmutableClass>>();

    // ...code...

    public void set(ArrayList<ArrayList<MyImmutableClass>> newArraylist)
    {
        arraylist = newArraylist;
    }

    public ArrayList<MyImmutableClass> get(int i)
    {
        return new ArrayList<MyImmutableClass>(arraylist.get(i));
    }
}

我意识到,通过使arraylist 易失性,我实际上并没有使其内容也易失性——我只是使对ArrayList&lt;ArrayList&lt;MyImmutableClass&gt;&gt; 对象的引用易失性。但是我不能完全理解的一件事是,如果set()get() 构建其new ArrayList&lt;MyImmutableClass&gt; 的过程中更改arraylist 的引用会发生什么?

我的直觉说这很好——arraylist.get(i) 传递给 ArrayList 的复制构造函数的引用不会改变,只有arraylist 持有的引用会被set() 改变——但我没有改变能够以某种方式找到明确的答案。

【问题讨论】:

  • 你害怕会发生什么?
  • 你在这里所做的实际上是CopyOnWriteArrayList背后的一般原则的一部分。
  • @Radiodef 怎么样?这里没有任何文字。
  • @shmosel 但是数组列表的易失性读取确保正确读取其内容如果对其内容的写入发生在易失性引用分配之前。 OP 的代码不是线程安全的,但这是 CopyOnWriteArrayList 等数据结构背后的一般原则。
  • @Radiodef 为什么这段代码不是线程安全的?

标签: java multithreading arraylist


【解决方案1】:

但有一件事我无法完全理解,如果 set() 在通过 get() 构造新的 ArrayList 的过程中更改 arraylist 的引用会发生什么?

在调用arraylist.get(i) 并将结果列表传递给new ArrayList&lt;MyImmutableClass&gt; 之后,更改arraylist 对该列表没有影响。更改变量的值不会影响对旧值执行的操作结果。而volatile其实与此无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多