【问题标题】:Establishing Happens-Before in Arrays在数组中建立 Happens-Before
【发布时间】:2012-08-04 04:23:59
【问题描述】:

有一个快速同步的问题,这是我的:

a) Class1 有一个并发哈希映射定义如下:

ConcurrentMap<String, int[][]> map  = new ConcurrentHashMap<String, int[][]>();

b) Class2 有一个线程,称为 Thread1。 Thread1 创建一个 Id 并检查 ma​​p 是否包含它。如果是,它检索值 (int[][]),修改内容并将其放回原处。如果没有,它会创建一个新的 int[][] 并存储它。这个检查->修改/创建的过程经常发生。

 private class Thread1 implements Runnable{

            public void run(){
                //keepRunning is volatile
                while( keepRunning ){

                  String id     = "ItemA";
                  int[][] value = map.get(id);

                  //If value is null, create an int[][] and put it back as value for Id
                  //If value is not null, modify the contents according to some logic  
                 }
             }
    }

c) 最后,我还有另一个线程,名为 Thread2。这个线程接受一个 id,检查地图是否有它的值。如果没有,什么都不会发生。如果是,那么它将 int[][] 中的值相加并使用该数字进行一些计算(此处没有修改)。

我想弄清楚我的操作是否是原子的。 b) 中的操作很好,因为数组的创建/修改和插入映射仅限于一个线程(Thread1)。

此外,由于插入到地图中会建立一个先发生操作,这将确保 c) 将在 int[][] 中看到更新的值。

但是,我不太确定如果 Thread2 在映射中查找相同的 int[][] 并尝试在 Thread1 修改它时对其进行总结会发生什么。

我认为 Thread2 会在 int[][] 中看到旧的(但未损坏的)值,我是否正确。原因是在 Thread1 完成将值放回映射之前,新的修改不会对 Thread2 可见。

非常感谢。

【问题讨论】:

标签: java multidimensional-array synchronization happens-before


【解决方案1】:

您的操作不是原子的,线程 2 将在线程 1 修改它们时尝试对这些值求和。

为避免您需要复制原件,请修改副本并放回副本。

【讨论】:

  • 嗨,汤姆,谢谢。或者,我可以不 a) 使用 AtomicReferenceArray b) 在 b) 中创建一个新数组(而不是从地图中获取旧数组),然后用它为特定的 Id 更新地图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多