Java 如何同步整数数组的单个元素?

Java 如何同步整数数组的单个元素?,java,arrays,synchronized,Java,Arrays,Synchronized,如果我想锁定整个阵列,我可以使用synchronized关键字如下: int arr[]; synchronized void inc(int a, int b){ arr[a]=arr[a]+b; } 但是我是否可以只锁定项arr[a],以便其他线程仍可以同时读取/写入数组的其他项?否,数组元素是基本元素,您无法锁定它们。(如果它们是对象也没用,因为锁定只对可变对象有帮助。您要锁定数组索引,而不是该索引处的内容) 唯一可能想到的构造是创建一个唯一引用数组索引的键,并在该索引上进行同

如果我想锁定整个阵列,我可以使用
synchronized
关键字如下:

int arr[];

synchronized void inc(int a, int b){
    arr[a]=arr[a]+b;
}

但是我是否可以只锁定项
arr[a]
,以便其他线程仍可以同时读取/写入数组的其他项?

否,数组元素是基本元素,您无法锁定它们。(如果它们是对象也没用,因为锁定只对可变对象有帮助。您要锁定数组索引,而不是该索引处的内容)

唯一可能想到的构造是创建一个唯一引用数组索引的键,并在该索引上进行同步(或使用),但只有当其他线程以相同的方式访问数组时,这才有帮助


我要说的是,改变设计,去掉int数组,使用一种数据结构,让您能够同步对其元素的访问(一个用集合包装的
列表。synchronizedList()
)这将是一个很好的起点。

也许更适合您的结构是
原子整数数组

不是现成的,但您可以创建一个与int数组大小相同的对象数组,并用不同的对象填充数组。因此,当您想要锁定int数组中的特定元素时,可以在相应的索引处锁定该对象:

final Object[] locks = new Object[arr.length]:
for(int i = 0; i < arr.length; i++) {
 locks[i] = new Object();
}

如果这真的是你的瓶颈,一个完全不同的结构可能更合适。如果你有8个内核,那么他们必须很忙,并且花费大约1/8的时间添加数字,以查看严重的冲突。如果执行此操作约占您工作的1/8,您应该设计系统,使其完全不锁定此操作

假设您需要在多个线程中获取大量值的总和。e、 g.计算发生的次数一个数字出现在一个很长的列表中

您可以有一个同步的计数器阵列,每个更新上都有一个非常昂贵的锁。(SYnchronized很快,但比add慢得多)


或者,您可以让所有线程保留它们自己的总数,并在最后进行汇总。最后的总数是一样的,只是你没有使用任何锁

这可能是最好的答案,但是Ray的答案是我在寻找具体案例的解决方案
synchronized(locks[a]) {
  // do something here
}