同步数组中的元素

use*_*404 2 java arrays multithreading wrapper thread-synchronization

我不熟悉Java中的多线程,也不太了解发生了什么.

从在线教程和讲义中,我知道synchronized必须应用于非null对象的块确保只有一个线程可以执行该代码块.由于数组是Java中的对象,因此可以对其应用同步.此外,如果数组存储对象,我应该能够同步数组的每个元素.

我的程序有几个线程更新了一个数组,因此我创建了一个Long对象数组:

synchronized (grid[arrayIndex]){
    grid[arrayIndex] += a.getNumber();
}
Run Code Online (Sandbox Code Playgroud)

这段代码位于run()我扩展的线程类的方法中.数组网格由我的所有线程共享.但是,在一个线程上运行相同的程序时,这不会返回正确的结果.

Gra*_*ray 7

这不行.重要的是要意识到grid[arrayIndex] += ...实际上是用grid新对象替换元素.这意味着您正在同步数组中的对象,然后立即将该对象替换为数组中的另一个对象.这将导致其他线程锁定不同的对象,因此它们不会阻塞.您必须锁定常量对象.

如果它永远不会被另一个数组对象替换,可以锁定整个数组对象:

synchronized (grid) {
    // this changes the object to another Long so can't be used to lock
    grid[arrayIndex] += a.getNumber();
}
Run Code Online (Sandbox Code Playgroud)

这是锁定final对象的良好模式的原因之一.有关详细信息,请参阅此答案:

为什么在布尔值上同步不是一个好习惯?