java - 在数组中建立 Happens-Before

标签 java multidimensional-array synchronization happens-before

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

a) Class1 的并发 HashMap 定义如下:

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,检查 map 是否有它的值。如果没有,什么也不会发生。如果是,则它将 int[][] 中的值相加,并使用该数字进行某些计算(此处不进行任何修改)。

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

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

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

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

非常感谢。

最佳答案

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

为避免这种情况,您需要复制原始文件,修改副本并放回副本。

关于java - 在数组中建立 Happens-Before,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11805878/

相关文章:

java - 将具有完全匹配(像素到像素)重叠的图像拼接在一起

java - 比较整数倒序的方法

java - 使用 2D Array 切换状态而不使用 Switch Case

java - 如何跨类使用同步块(synchronized block)?

Java应用程序启动一个进程并在进程中发生事件时获取回调

JAVA:按下按钮时 JCheckBox 在 JTable 中丢失选择

PHP 在多维数组中查找值

PHP 不敏感多重排序

android - 选择哪一个 : Android Service or Intent Service or Async Task to Sync Files

java - HttpSession 中的同步是否可行?