Item 66: Synchronize access to shared mutable data

Proper use of synchronization guarantees that no method will ever observe the object in an inconsistent state.

 

Without synchronization, one thread’s changes might not be visible to other threads.

 

The language specification guarantees that reading or writing a variable is atomic unless the variable is of type long or double.


Synchronization is required for reliable communication between threads as well as for mutual exclusion.

 

Do not use Thread.stop which is unsafe.


In the absence of synchronization, it’s quite acceptable for the virtual machine to transform this code:

while (!done)
i++;

 

into this code:

if (!done)
while (true)
i++;

 

This optimization is known as hoisting, and it is precisely what the HotSpot server VM does. The result is a liveness failure. One way to fix the problem is to synchronize access to the "done" field. In fact, synchronization has no effect unless both read and write operations are synchronized if you want it for for its communication effects. While the volatile modifier performs no mutual exclusion, it guarantees that any thread that reads the field will see the most recently written value.

 

The increment operator (++) is not atomic. It performs two operations on the incremented field: first it reads the value, then it writes back a new value, equal to the old value plus one. If a second thread reads the field between the time a thread reads the old value and writes back a new one, the second
thread will see the same value as the first and return the same serial number. This is a safety failure: the program computes the wrong results.

 

The best way to avoid the problems discussed in this item is not to share mutable data. Either share immutable data, or don’t share at all. In other words, confine mutable data to a single thread.

 

It is acceptable for one thread to modify a data object for a while and then to share it with other threads, synchronizing only the act of sharing the object reference. Other threads can then read the object without further synchronization, so long as it isn’t modified again. Such objects are said to be effectively immutable. Transferring such an object reference from one thread to others is
called safe publication. There are many ways to safely publish an object reference: you can store it in a static field as part of class initialization; you can store it in a volatile field, a final field, or a field that is accessed with normal locking; or you can put it into a concurrent collection.

 

In summary, when multiple threads share mutable data, each thread that reads or writes the data must perform synchronization.

你可能感兴趣的:(thread,Access)