1. Synchronization involves two aspects: atomicity and visibility.
2. Visibility: in multi-threaded programs, if correct synchronization is not used, some threads will get invalid data.
- The Java memory model requires that the read and write operations on variables must be atomic, but for non-volatile long and double variables, JVM allows 64-bit read or write operations to be divided into two 32-bit operations. When reading a non-volatile long variable, if the read and write operations on the variable are executed in different threads, it is likely to read the 32-bit high of a value and the 32-bit low of another value. Even if you do not consider invalid data, it is insecure to use shared and variable variables such as long and double in a multi-threaded program unless you declare them with the keyword volatile, or use a lock to protect it.
- The meaning of locking is not only limited to mutex, but also includes memory visibility. To ensure that all threads can see the latest value of the shared variable, all threads that execute read or write operations must be synchronized in the same lock.
ready = number = 0 ReaderThread (! } } = 42=
3. volatile variable: Used to notify other threads of variable update operations. When the variable is declared as volatile, the compiler and runtime will notice that the variable is shared, so operations on the variable will not be reordered together with other memory operations. Volatile variables are not cached in registers or invisible to other processors. Therefore, the latest written values are always returned when you read volatile variables.
- The locking mechanism ensures both visibility and atomicity, while volatile variables only ensure visibility.
- The volatile variable should be used only when all of the following conditions are met:
4. Closed threads: synchronization is usually required to access Shared variable data. One way to avoid synchronization is not to share data. If you only access data in a single thread, you do not need to synchronize data. This technology is called thread blocking.
Three methods:
5. immutability: immutable objects must be thread-safe.
When the following conditions are met, the object is unchangeable:
6. the following Holder class is "not correctly published". It has two problems. First, in addition to the thread that publishes the object, other threads can see that the Holder field is an invalid value, so we will see an empty reference or an old value. However, even worse, the thread will see that the value referenced by Holder is the latest, but the value in the Holder status is invalid. It is even more unpredictable that a thread gets an invalid value when it reads the domain for the first time, and an updated value when it reads the domain again. This is why assertSainty throws AssertionError.
Holder( n) .n = (n != AssertionError("This statement is false" } } }