Is synchronization needed when manipulating differ

2019-07-16 14:09发布

问题:

In the context if Java, I have a code like this,

MyObject[] array;

and in different threads i have a code like this

array[i] = new MyObject(val);

If I ensure that each of my threads use different values of "i" then would I need to synchronize the above statement to take care of race conditions?

回答1:

Race conditions are only an issue if two threads may read and modify the same variable concurrently.

As long as you are sure that each thread uses a different range of indices, and the underlying array is not redefined, then it should be safe to think of each cell as a different variable. Therefore, each thread works on a separate set of variables and you would not get a race condition.

That being said, make sure you are indeed not overlapping in your use of indices - this is often trickier than it would appear.

In addition, you have to make sure that no two cells map into the object - if you modify the same object (rather than just the reference to it) from two threads, you could get a race condition.



回答2:

Maybe. If every task wrote to a different location in the array, they wouldn't overwrite each other's output. So that works.

You might face an issue when finally processing the array, though, since Java doesn't make guarantees when the values are written to memory. The optimizer could decide to write the values really late (or too late for you). Therefore, you should make the array volatile which means that no caching must happen when accessing the values in it.



回答3:

If you're absolutely certain that each thread will always access a different index, then you don't need to synchronize those accesses.

BUT you do need to make sure that the reference to the array is properly published to the different threads-- in practice that usually means the reference needs to be final or volatile.



回答4:

There are three discreet points of interest with synchronization here.

The array variable itself: Declaring the variable array as volatile or final (or synchronizing on array) is important so that both threads are guaranteed to access the same instanced array. The following is possible if not:

  1. Threads A and B start up
  2. Thread A instances array as a new Array object
  3. Thread B tries to access thread A's array, but gets a NullPointerExceptoin because it does not see Thread A's assignment of a new array to array yet.

Not good.

The array references to MyObject instances (and what seems to be Venkatraman's actual question): With the array variable itself properly synchronized, then yes, the two threads can access different elements in the array safely. Once the child thread has finished doing whatever it was doing, then the 'master' thread will want to synchronized the array to ensure it gets the final state of the child's array elements before using them.

The MyObject instances themselves, but that seems outside the scope of the question