Java:如何同步数组访问以及在同步条件下进行的操作有哪些限制 [英] Java: how to synchronize array accesses and what are the limitations on what goes in a synchronized condition

查看:54
本文介绍了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

已同步(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不提供多维数组,仅提供数组数组,因此您当然可以在嵌套数组上进行同步,以实现更细粒度的同步.如果将2d数组建模为行数组,则只能在行上同步,而不能在列上同步,因为在该示例中,列未表示为单独的数组.

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.

课程:

  • 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:如何同步数组访问以及在同步条件下进行的操作有哪些限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆