Java: how to synchronize access to an array and what are the restrictions on what goes in a synchronized state

I had a 2x2 array in which two threads worked.

can i use a synchronized statement in java for an array?

How does blocking work? the java tutorial thread says that the synchronized statement works with objects, so I was not sure what they meant. Another site said that I can make an expression like

synchronized (array1[]){ } 

Does this synchronization access the entire array so that the array is blocked for other threads?

If I have a two-dimensional array, I can use

synchronized (array1[i]) to lock one of the array rows?

and is it possible to block individual array values ​​with something like

 synchronized (array1[i][j]){ } 

But yes, advice or help is greatly appreciated. In fact, I already turned it on, right or wrong. But I want to know for future use.

+8
java synchronization
source share
4 answers

Yes, you can synchronize the use of an array as a monitor object, because arrays (even arrays of primitives) are objects in Java.

You can synchronize the code block on a specific monitor as follows:

 public void myMethod() { unsynchronized_statements... synchronized(myMonitorObject) { synchronized_statments... } 

It’s best to sync as few lines of code as possible.

The synchronization of the code on the monitor does not affect the monitor in any way, it only affects the threads accessing the synchronized block of code. Before a thread can enter a code block, it must receive a “lock” on the monitor. Java runtime ensures that no more than one thread at a time can have a "lock" on the monitor. Thus, synchronization on your array does not prohibit unsynchronized blocks of code from accessing it! The trick is to make sure that all operations that you do not want to perform at the same time are in blocks synchronized to the same monitor.

Since Java does not offer multidimensional arrays, only arrays of arrays, you can, of course, synchronize with a nested array for finer synchronization. If you model a 2d array as an array of rows, you can only synchronize rows, not columns, because in this example, columns are not represented as separate arrays.

You can only synchronize values ​​of one array if they are not primitve, therefore Integer () instead of int. Please note that Integer () is an immutable object, so you cannot change its value. The solution would be to create your own Cell () shell object using getter and setter for the contained numeric value. This will allow you to allow the thread to obtain a lock in the cell and safely change its value.

Since it was my day off, I decided to have fun and created a working example of what you described. Yes, it is my idea to have fun.

Classes:

The application starts several operations with the same matrix. The only synchronized code block is in the Operation class. If you delete synchronization, the results will be erroneous, because two operations simultaneously process the same line.

Sync output:

 [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] 

Example output in the absence of synchronization:

 [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] 

Note that I have added some Thread.sleep () statements in the implementation of the operations to make the difference between synchronized and unsynchronized execution more obvious.

+11
source share

No, synchronizing this method only means locking the array object, and not synchronizing access to its methods. If your array is visible to others, they can still access it or modify its contents regardless of whether it is locked. Only they cannot block it at the same time - if they try (from another thread), they will be blocked until the blocking is released by its original buyer.

If you want only one thread to access your array (or one of its elements) at a time, you need to encapsulate it in a class and synchronize all the methods of the open class that control the array. (You can lock the array for this purpose, although if you want, a simpler and more ordinary approach is to declare the methods themselves as synchronized , in which case their contents are synchronized with this , covering the object).

 class ArrayWrapper { private int[] array = ...; public void setValue(int index, int value) { synchronized (array) { array[index] = value; } } public int getValue(int index) { synchronized (array) { return array[index]; } } ... } 
+3
source share

The synchronized only works with objects.

Array synchronization only blocks an array (in Java, an array is an object).

If you synchronize on an individual element of an array, then suppousing they are objects, not primitives, that is, another other lock. You can have one without the other, and the inversion is also true. You cannot synchronize a primitive.

If you need to prevent the simultaneous modification of the array, synchronize each access to the array on some object. You can use any object that you want for this purpose, but it must be the same for the job. Please note: if you access a shared resource with synchronization in other parts of the code that you access without synchronization or synchronization on another object, then this is useful for nothing.

+3
source share

When synchronizing an object or array, you prevent the synchronization of a different thread than the same object. This does not stop you from using the object, and no other operation is "blocked". You must make sure that you lock the object first in a consistent way so that it "locks" the object.

+1
source share

All Articles