Java:如何同步数组访问以及对同步条件中的内容有何限制

我有一个2×2阵列,我有两个线程在运行.

可以在数组中使用java中的synchronized语句吗?

锁定如何工作? java教程线程说同步语句适用于对象,所以我不确定它们是什么意思.另一个网站说我可以发表一个声明

synchronized (array1[]){

}

这是否同步访问数组中的所有内容,以便将数组锁定到其他线程?

如果我有一个二维数组我可以使用

synchronized(array1 [i])来锁定数组的一行?

是否可以锁定单个数组值
喜欢的东西

synchronized (array1[i][j]){

}

但是,非常感谢提示或帮助.实际上我已经把它打开了,无论是否正确.但我想知道将来使用

解决方法:

是的,您可以使用数组作为监视器对象进行同步,因为数组(甚至是基元数组)是Java中的对象.

您可以在特定监视器上同步代码块,如下所示:

public void myMethod() {

    unsynchronized_statements...

    synchronized(myMonitorObject) {
        synchronized_statments...
    }

最佳做法是尽可能少地同步代码行.

在监视器上同步代码不会以任何方式影响监视器,它只影响访问同步代码块的线程.在线程执行可以进入代码块之前,它必须在监视器上获得“锁定”. Java运行时确保一次最多一个线程可以在监视器上具有“锁定”.因此,在数组上进行同步不会禁止不同步的代码块来访问它!诀窍是确保您不希望同时发生的所有操作都在同一监视器上同步的块内.

由于Java不提供多维数组,只提供数组数组,因此您可以在嵌套数组上进行同步,以实现更细粒度的同步.如果将2d数组建模为行数组,则只能在行上而不是在列上进行同步,因为在该示例中,列不表示为单独的数组.

如果这些值是非原始值,则只能对单个数组值进行同步,因此Integer()而不是int.请注意,Integer()是一个不可变对象,因此您无法更改其值.一个解决方案是使用getter和setter为包含的数值创建自己的Cell()包装器对象.这将允许您让一个线程获取Cell上的锁并安全地更改其值.

因为这是我的休息日,所以我决定玩得开心,并创建了一个你所描述的实例.是的,这是我开心的想法.

类别:

> Matrix:表示2d细胞矩阵
> Cell:矩阵单元格值的包装器
> Operation:对单元格数组的抽象操作
> IncrementOperation:增加每个Cell值的操作
> ReverseOperation:一种颠倒细胞顺序的操作
> Main:申请

应用程序在同一矩阵上启动多个操作.唯一的同步代码块在类Operation中.如果删除同步,结果将是错误的,因为两个操作同时操作同一行.

同步输出:

[105, 104, 103, 102, 101]
[110, 109, 108, 107, 106]
[115, 114, 113, 112, 111]
[120, 119, 118, 117, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 134, 133, 132, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]

NOT同步时的输出示例:

[105, 4, 103, 102, 101]
[110, 9, 108, 207, 106]
[115, 14, 113, 212, 111]
[120, 19, 118, 217, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 34, 133, 232, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]

请注意,我在操作实现中添加了一些Thread.sleep()语句,以使同步和非同步执行之间的区别更加明显.

上一篇:java – 实践中的并发设计原则


下一篇:c – 有没有办法同步考虑崩溃的进程?