insumity
insumity

Reputation: 5459

Does a non-volatile variable need synchronized?

Consider 2 threads and an array int[] values. The first thread is performing:

synchronized (values) {
     values[i] = 58;
}

while the second thread is performing:

if (values[i] == 58) {
}

outside a synchronized block.

If the first thread first performs values[i]= 58, is it guaranteed that if the second threads executes slightly later, that the if of the second thread reads 58 even though the second thread reads values[i] outside a synchronized block?

Upvotes: 0

Views: 111

Answers (2)

nyarian
nyarian

Reputation: 4365

Aforementioned behavior is not guaranteed. The guarantee of such a "visibility" is actually a subject of happens-before relationship:

The key to avoiding memory consistency errors is understanding the happens-before relationship. This relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement.

Happens-before relationship (according to JLS) can be achieved as such:

  1. Each action in a thread happens-before every action in that thread that comes later in the program's order.
  2. An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.
  3. A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.
  4. A call to start on a thread happens-before any action in the started thread.
  5. All actions in a thread happen-before any other thread successfully returns from a join on that thread.

So, in your particular case, you actually need either synchronization using a shared monitor or AtomicIntegerArray in order to make access to the array thread-safe; volatile modifier won't help as is, because it only affects the variable pointing to the array, not the array's elements (more detailed explanation).

Upvotes: 1

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 78995

If the first thread first performs values[i]= 58, is it guaranteed that if the second threads executes slightly later, that the if of the second thread reads 58 even though the second thread reads values[i] outside a synchronized block?

No

Synchronising this way does not stop other threads to perform any operation on the array simultaneously. However, other threads will be prevented to grab a lock on the array.

Upvotes: 2

Related Questions