(In concurrent programming, we need to deal with two key issues: how to communicate between threads and how to synchronize between threads (threads here refer to concurrent execution of active entities). Communication refers to the mechanism by which threads exchange information. In imperative programming, there are two communication mechanisms between threads: shared memory and message passing. In the shared memory concurrency model, the common state of programs is shared among threads, and threads communicate implicitly by reading and writing the common state in memory. In the concurrency model of message passing, there is no common state between threads. Threads must communicate explicitly by explicitly sending messages.
Synchronization is a mechanism used by programs to control the relative order of operations between different threads. In the shared memory concurrency model, synchronization is done explicitly. The programmer must explicitly specify that a method or piece of code needs to be mutually exclusive between threads. In the concurrency model of messaging, synchronization is implicit because the message must be sent before it is received.
Java concurrency adopts the shared memory model. The communication between Java threads is always implicit, and the whole communication process is completely transparent to programmers. If Java programmers writing multithreaded programs do not understand how implicit inter thread communication works, they are likely to encounter various strange memory visibility problems.)