如何在没有同步的情况下从多个线程修改2D数组

时间:2014-10-09 06:03:57

标签: java data-structures

如何在java中设计2D数组,使其允许多个线程在不使用同步的情况下修改或插入特定位置的值

5 个答案:

答案 0 :(得分:2)

如果没有同步,你就无法做到。你唯一能做的就是减少锁定范围。如果您还不知道,请阅读有关锁定粗化的信息。 ConcurrentHashMap使用它。想法是,不是将整个数组锁定到修改,而是锁定一段数组(例如:开始,中间或结束),在那里进行修改。这使得数组DS保持打开以供其他线程读取和写入,并且除非2个线程试图同时改变同一段,否则不会发生阻塞。

答案 1 :(得分:2)

有几种方法可以做到。

首先,如果您想要最大并发作为公共库,无论有多少线程访问矩阵,并且您的int[][]相当小,您可以这样做。

  1. 设置AtomicBoolean矩阵等于int[][]的维度。
  2. 当您尝试更新int矩阵时,首先锁定AtomicBoolean,使用Unsafe.putIntVolatile()以volatile方式更新值,然后取消AtomicBoolean
  3. 其次,如果您事先知道线程数。

    1. 按照int这样的线程保留标记对象/值;然后创建一个额外的int [] []作为标记矩阵。将标记矩阵初始化为某个虚拟值,该虚拟值不等于任何线程标记值,例如-1。
    2. 在尝试更新int矩阵时,首先使用Unsafe.compareAndSet()将单元格锁定在thr标记矩阵中;然后按Unsafe.putIntVolatile()更新;最后通过将值重置为-1来取消标记标记矩阵。
    3. 最后,如果你能够容忍int[][]在实际代码中真的不是int矩阵,你可以做的是使用long[][]矩阵,其中前32位是值的最新更新次数和最后32位是当前值。然后,您可以轻松地使用Unsafe.compareAndSet()将此长值设置为整体。请注意,您可以循环显示高32位值,这样您就不必拥有更新上限== Integer.MAX_VALUE

答案 2 :(得分:1)

这个问题有意义吗?如果我们假设int[][]上的所有操作都是原子的,那么就不需要同步了!但令我困惑的是:在声明数组边界后,不能在更改数组边界时插入值。

答案 3 :(得分:1)

如果可以保证数组的每个元素只能被一个线程访问(直到你完成了可以改变数组内容的计算),那么你可以安全地使用许多线程。 (因为他们会有效独立)否则,这可能是一个坏主意......

答案 4 :(得分:0)

创建一个static变量,您的所有Thread都可以访问该变量:

public class MainClass {

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                Constants.intValue[0][0] = new Integer(10);
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                Constants.intValue[0][1] = new Integer(20);
            }
        });

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                for (Integer[] valueArr : Constants.intValue) {
                    for (Integer intValue : valueArr) {
                        System.err.println(intValue);
                    }
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();

    }

}

interface Constants {

    Integer[][] intValue = new Integer[2][2];

}

如果它使用相同的数组位置,则唯一的情况是下一个线程将覆盖先前的设置值。