How to change a 2D array from multiple threads without synchronization

How to create a 2D array in Java so that it allows multiple threads to change or insert a value at a specific position without using synchronization.

+5
source share
5 answers

Well, you cannot do this without synchronization. The only thing you can do is reduce the amount of lock it uses. If you do not already know, read about capping the castle. ConcurrentHashMap uses it. The idea is that instead of blocking the entire array before the modifications, you simply block the segment of the array (for example: beginning, middle or end) where the modification will take place. This keeps the DS array open for reading and writing by other threads, and no lock will happen unless two threads try to change the same segment at the same time.

+2
source

If you can guarantee that each element of the array (s) is accessible only ever by a single thread (until you complete a calculation that can change the contents of the array), you can safely use many threads. (because they will be effectively independent) Otherwise, this is probably a bad idea ...

+2
source

There are several ways to do this.

Firstly, if you want the maximum concurrency to be a shared library, no matter how many threads access the matrix, and your int[][] is small enough, you can do this as follows.

  • The AtomicBoolean matrix AtomicBoolean is equal to the size of int[][] .
  • While you are trying to update the int matrix, first block AtomicBoolean , use Unsafe.putIntVolatile() to update the value in a volatile way, and then reset AtomicBoolean .

Secondly, if you know the number of threads in advance.

  • Store marker object / value according to stream, for example int; then create an additional int [] [] as a marker matrix. Initialize the marker matrix to some dummy value that is not equal to any of your stream marker values, for example. -1.
  • While you are trying to update the int matrix, lock the cell in the thr marker matrix, using Unsafe.compareAndSet() ; then update it Unsafe.putIntVolatile() ; and finally cancel the marker matrix to reset the value -1. A.

Finally, if you can tolerate int[][] , in fact this is not an int matrix in the actual code, then you can use the long[][] matrix, where the first 32 bits are the current number of updates for the value and the last 32 bits are the current value. Then you can easily use Unsafe.compareAndSet() to set this long value as a whole. Note that you can copy the upper 32-bit value, so you do not need to have the upper update limit == Integer.MAX_VALUE .

+2
source

Does this question make sense? If we assume that int[][] all operations on it will be atomic, so there should be no synchronization! But what confuses me the question: you cannot insert values ​​into the tool for changing the boundaries of the array after you declared it.

+1
source

Create a static variable that can be accessed by all of your Thread as follows:

 public class MainClass { public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { Constants.intValue[0][0] = new Integer(10); } }); Thread t2 = new Thread(new Runnable() { public void run() { Constants.intValue[0][1] = new Integer(20); } }); Thread t3 = new Thread(new Runnable() { public void run() { for (Integer[] valueArr : Constants.intValue) { for (Integer intValue : valueArr) { System.err.println(intValue); } } } }); t1.start(); t2.start(); t3.start(); } } interface Constants { Integer[][] intValue = new Integer[2][2]; } 

The only case would be the next thread will override the previous setpoint if it uses the same array position.

0
source

Source: https://habr.com/ru/post/1204301/


All Articles