Java: how to synchronize array accesses and what are the limitations on what goes in a synchronized condition(Java:如何同步数组访问以及同步条件下的限制是什么)
问题描述
我有一个 2x2 数组,我有两个线程在上面运行.
I had a 2x2 array that I had two threads operating on.
可以在java中对数组使用同步语句吗?
it is possible to use a synchronized statement in java on an array?
锁定是如何工作的?java教程线程说同步语句适用于对象,所以我不确定它们的含义.另一个网站说我可以发表这样的声明
how does the locking work? the java tutorial thread said that the synchronized statement works on objects, so I wasn't sure what they meant. Another site said that I could make a statement like
synchronized (array1[]){
}
这是否会同步对数组中所有内容的访问,以便将数组锁定到其他线程?
Does this synchronize accesses to everything in the array so that the array is locked to other threads?
如果我有一个二维数组,我可以使用
if I have a two-d Array can i use
synchronized (array1[i])
锁定数组的其中一行?
synchronized (array1[i])
to lock one of the rows of the array?
是否可以锁定单个数组值像
and is it possible to lock individual array values with something like
synchronized (array1[i][j]){
}
但是,非常感谢您提供提示或帮助.其实我已经上交了,正确与否.但我想知道以备将来使用
But yeah, tips or help are greatly appreciated. Actually I already turned it in, correct or not. But I want to know for future use
推荐答案
是的,您可以使用数组作为监控对象进行同步,因为数组(甚至是基元数组)是 Java 中的对象.
Yes, you can synchronize using an array as monitor object, because arrays (even arrays of primitives) are objects in Java.
您可以像这样在特定监视器上同步代码块:
You can synchronize a block of code on a specific monitor like this:
public void myMethod() {
unsynchronized_statements...
synchronized(myMonitorObject) {
synchronized_statments...
}
最佳做法是同步尽可能少的代码行.
It is best practice to synchronize as few lines of code as possible.
在监视器上同步代码不会以任何方式影响监视器,它只会影响访问同步代码块的线程.在线程执行可以进入代码块之前,它必须获得监视器上的锁".Java 运行时确保一次最多有一个线程可以在监视器上拥有锁".因此,在您的数组上同步不会禁止未同步的代码块访问它! 诀窍是确保您不想同时发生的所有操作都在同步的块内同一台显示器.
Synchronizing code on a monitor does not affect the monitor in any way, it only affects the threads accessing the synchronized block of code. Before thread execution can enter the block of code, it must obtain 'the lock' on the monitor. The Java runtime ensures that at most one thread at a time can have 'the lock' on a monitor. So synchronizing on your array does not prohibit unsynchronized blocks of code to access it! The trick is to make sure that all the operations you don't want to happen at the same time are within blocks synchronized on the same monitor.
由于 Java 不提供多维数组,只提供数组数组,因此您当然可以在嵌套数组上进行同步以实现更细粒度的同步.如果将二维数组建模为行数组,则只能在行上同步,而不是在列上同步,因为在该示例中,列未表示为单独的数组.
Since Java does not offer multi-dimensional arrays, only arrays-of-arrays, you can certainly synchronize on a nested array for more fine-grained synchronization. If you model a 2d array as an array of rows, you can only synchronize on rows, not on columns because in that example columns are not represented as separate arrays.
如果它们是非原始的,则只能在单个数组值上进行同步,因此使用 Integer() 而不是 int.请注意, Integer() 是一个不可变对象,因此您将无法更改其值.一种解决方案是使用包含数值的 getter 和 setter 创建您自己的 Cell() 包装器对象.这将允许您让线程锁定 Cell 并安全地更改其值.
You can only synchronize on single array values if these are non-primitve, so Integer() instead of int. Note that Integer() is an immutable object, so you would not be able to change its value. A solution would be to create your own Cell() wrapper object with a getter and setter for the contained numeric value. This would allow you to let a thread get a lock on the Cell and safely change its value.
因为今天是我的休息日,所以我决定找点乐子,并根据您的描述创建了一个工作示例.是的,这就是我的乐趣.
Because it's my day off I decided to have some fun and created a working example of what you describe. Yes, this is my idea of having fun.
类:
- 矩阵 :表示二维单元格矩阵
- 细胞 : 矩阵单元格值的包装器
- 操作 : 对 Cells 数组的抽象操作
- IncrementOperation :增加每个单元格值的操作
- ReverseOperation : 反转单元格顺序的操作
- 主要 : 应用程序
- Matrix : representation of a 2d matrix of cells
- Cell : wrapper for a matrix cell value
- Operation : An abstract operation on an array of Cells
- IncrementOperation : an Operation which increments each Cell value
- ReverseOperation : an Operation which reverses the order of the cells
- Main : the application
应用程序在同一个矩阵上启动多个操作.唯一同步的代码块在 Operation 类中.如果取消同步,结果将是错误的,因为两个操作同时操作同一行.
The application starts multiple operations on the same matrix. The only synchronized block of code is in the class Operation. If you remove the synchronization, the results will be wrong because two operations are manipulating the same row simultaneously.
同步时的输出:
[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() 语句,以使同步和非同步执行之间的区别更加明显.
Note that I added some Thread.sleep() statements in the operation implementations to make the difference between synchronized and unsynchronized execution more obvious.
这篇关于Java:如何同步数组访问以及同步条件下的限制是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java:如何同步数组访问以及同步条件下的限制是什么
基础教程推荐
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01