Thread synchronization and multi-thread communication


1. What is thread synchronization

When a thread is operating on the memory, other threads cannot operate on this memory address. Until the thread completes the operation, other threads can operate on the memory address, and other threads are waiting. This is the thread Synchronize

Two, several ways of thread synchronization

  • A synchronized method
    is a method modified with the synchronized keyword. Since each object of java has a built-in lock, when the method is modified with this keyword, the built-in lock will protect the entire method. Before calling this method, the built-in lock needs to be obtained, otherwise it will be in a blocked state. It should be noted that the synchronized keyword can also modify the static method, and if the static method is called at this time, the entire class will be locked.
  • Synchronized code block
    is a statement block modified by the synchronized keyword. The statement block modified by this keyword will automatically be added with a built-in lock to achieve synchronization. It should be noted that synchronization is an expensive operation, so the content of synchronization should be minimized. Usually it is not necessary to synchronize the entire method, just use the synchronized code block to synchronize the key code.
  • ReentrantLock
    Java 5 has added a java.util.concurrent package to support synchronization. The ReentrantLock class is a reentrant, mutually exclusive lock that implements the Lock interface. It has the same basic behavior and semantics as using synchronized, and extends the its ability. It should be noted that ReentrantLock also has a construction method that can create a fair lock, but it is not recommended because it can greatly reduce the efficiency of the program.
  • volatile
    The volatile keyword provides a lock-free mechanism for domain variable access. Using volatile to modify the domain is equivalent to telling the virtual machine that the domain may be updated by other threads, so every time the domain is used, it must be recalculated instead of using registers. value in . It should be noted that volatile does not provide any atomic operations, nor can it be used to modify variables of final type.

3. The communication method between multiple threads in Java

  • wait()、notify()、notifyAll()

If synchronized is used between threads to ensure thread safety, wait(), notify(), and notifyAll() can be used to realize thread communication. These three methods are not methods declared in the Thread class, but methods declared in the Object class.

The wait() method allows the current thread to release the object lock and enter the blocked state.

The notify() method is used to wake up a thread that is waiting for the corresponding object lock, so that it enters the ready queue, so that after the current thread releases the lock, it can compete for the lock, and then get the execution of the CPU.

notifyAll() is used to wake up all threads that are waiting for the corresponding object lock, so that they enter the ready queue, so that they can compete for the lock after the current thread releases the lock, and then get the execution of the CPU.

  • await()、signal()、signalAll()

If Lock is used between threads to ensure thread safety, await(), signal(), signalAll() can be used to implement thread communication. These three methods are methods in the Condition interface, which appeared in Java 1.5, and it is used to replace the traditional wait+notify to realize the cooperation between threads, and its use depends on Lock.

In fact, await()/signal()/signalAll() has a natural correspondence with wait()/notify()/notifyAll(). That is: await() in Condition corresponds to wait() of Object, signal() in Condition corresponds to notify() of Object, and signalAll() in Condition corresponds to notifyAll() of Object.

  • message queue

Threads need to communicate. The most classic scenario is the producer-consumer model, and BlockingQueue is the solution for this model.

Although BlockingQueue is also a sub-interface of Queue, its main purpose is not as a container, but as a tool for thread communication. BlockingQueue has a characteristic: when the producer thread tries to put elements into the BlockingQueue, if the queue is full, the thread is blocked; when the consumer thread tries to take out elements from the BlockingQueue, if the queue is empty, the thread Threads are blocked The two threads of the program can control the communication of the threads by alternately putting elements into and taking out elements from the BlockingQueue.

Guess you like

Origin blog.csdn.net/weixin_44153131/article/details/129784859