是的,您可以使用数组作为监视对象进行同步,因为数组(甚至基元数组)都是Java中的对象。
您可以像这样在特定的监视器上同步代码块:
public void myMethod() { unsynchronized_statements... synchronized(myMonitorObject) { synchronized_statments... }最佳实践是同步尽可能少的代码行。
在监视器上同步代码不会以任何方式影响监视器,它只会影响访问同步代码块的线程。在线程执行可以输入代码块之前,它必须在监视器上获得“锁”。Java运行时确保一次最多一个线程可以在监视器上拥有“锁”。
因此,在您的数组上进行同步并不会禁止未同步的代码块访问它! 诀窍是确保所有您不想同时发生的操作都在同一监视器上同步的块内。
由于Java不提供多维数组,仅提供数组数组,因此您当然可以在嵌套数组上进行同步以实现更细粒度的同步。如果将2d数组建模为行数组,则只能在行上同步,而不能在列上同步,因为在该示例中,列未表示为单独的数组。
如果它们不是非原始的,则只能对单个数组值进行同步,因此要使用Integer()而不是int。请注意,Integer()是不可变的对象,因此您将无法更改其值。一种解决方案是使用包含的数值的getter和setter创建自己的Cell()包装器对象。这将允许您让线程锁定单元格并安全地更改其值。
因为今天是我的休息日,所以我决定找点乐子,并创建了一个描述您所描述内容的有效示例。是的,这是我玩的想法。
类:
- 矩阵:细胞二维矩阵的表示
- 单元格:矩阵单元格值的包装器
- 操作:对单元格数组的抽象操作
- IncrementOperation:增加每个像元值的操作
- ReverseOperation:反转单元顺序的操作
- 主要:应用程序
该应用程序在同一矩阵上启动多项操作。唯一的同步代码块在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]
不同步时的示例输出:
[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()语句,以使同步执行和非同步执行之间的区别更加明显。



