Not only do we want to prevent a thread from using object state while other threads are modifying that state, and you want other threads to see the state change that occurs when a thread modifies the state of the object.
Visibility: when read and write operations are performed on different threads, their actions are shared and visible. In order to ensure that the operation of memory writes between multiple threads is visible, the synchronization mechanism must be used.
minimum Security: The thread obtains at least one valid value, rather than a random value, in the absence of a synchronization mechanism.
volatile variables: We can use lock to implement thread synchronization, but Java also provides a slightly weaker synchronization mechanism, volatile variables, to ensure that the update operation of variables is notified to other threads. When we declare a variable as a volatile variable, both the compiler and the runtime notice that the variable is shared, so the volatile variable is not cached in the register or the other processor cannot see it, so our reading of the volatile variable is always the most recently written value. The use of volatile variables can effectively ensure that a thread cannot read the latest value of a variable.
Thread closure: When accessing shared mutable data, synchronization is often required, and one way to avoid using synchronization is to not share data. If the data is accessed only in single-wire range, then no synchronization is required, and this is thread closure.
Stack closure: In a stack closure, objects can only be accessed through local variables.
Java Concurrency-Object sharing