在阵列中建立先发生的事件

时间:2012-08-04 04:24:00

标签: java multidimensional-array synchronization happens-before

快速同步问题,这就是我所拥有的:

a) Class1 具有如下定义的并发哈希映射:

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

b) Class2 有一个名为 Thread1 的主题。 Thread1会创建 ID 并检查地图是否包含它。如果是,则检索值(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可见。

非常感谢。

1 个答案:

答案 0 :(得分:1)

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

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