如何在java中设计2D数组,使其允许多个线程在不使用同步的情况下修改或插入特定位置的值
答案 0 :(得分:2)
如果没有同步,你就无法做到。你唯一能做的就是减少锁定范围。如果您还不知道,请阅读有关锁定粗化的信息。 ConcurrentHashMap使用它。想法是,不是将整个数组锁定到修改,而是锁定一段数组(例如:开始,中间或结束),在那里进行修改。这使得数组DS保持打开以供其他线程读取和写入,并且除非2个线程试图同时改变同一段,否则不会发生阻塞。
答案 1 :(得分:2)
有几种方法可以做到。
首先,如果您想要最大并发作为公共库,无论有多少线程访问矩阵,并且您的int[][]
相当小,您可以这样做。
AtomicBoolean
矩阵等于int[][]
的维度。AtomicBoolean
,使用Unsafe.putIntVolatile()
以volatile方式更新值,然后取消AtomicBoolean
。其次,如果您事先知道线程数。
Unsafe.compareAndSet()
将单元格锁定在thr标记矩阵中;然后按Unsafe.putIntVolatile()
更新;最后通过将值重置为-1来取消标记标记矩阵。最后,如果你能够容忍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];
}
如果它使用相同的数组位置,则唯一的情况是下一个线程将覆盖先前的设置值。