Understanding Java volatile and Synchronized knowledge points

Under java multithreading, if concurrent operations are performed on a shared variable, it will cause thread safety issues

Prerequisite understanding

volatile keyword:

      In a concurrent environment, each thread will have its own working memory, each thread can only access its own working memory, and shared variables will be loaded into the working memory of each thread, so there is a problem here, memory When is the data loaded into the thread's working memory, and when will the contents of the thread's working memory be written back to the variable memory. Improper handling of these two steps will cause data inconsistency. For example, a shared variable is modified by thread A, but it is not written back to memory, and thread B reads the shared variable after loading the data in memory It is dirty data. The correct approach is that the modification of thread A should be visible to thread B.

  One supplement to memory visibility is that the reason why the shared variable values ​​seen by multiple threads are different is because when threads are occupying CPU time, the cpu will not directly interact with the memory in order to increase the processing speed, but The shared content in the memory will be first read into the internal cache space, and then the cpu will only interact with the internal cache space during processing. This processing method will cause memory visibility problems in a multi-core machine.

  Volatile can solve the memory visibility problem in a concurrent environment. You only need to add the volatile keyword in front of the shared variable to solve it. However, it should be noted that volatile only solves the memory visibility problem. It is still necessary for problems like i++ Use other methods to ensure thread safety. The principle of using volatile to solve the memory visibility problem is that if a write operation is performed on a shared variable modified by volatile, the JVM will send a Lock prefix instruction to the cpu, and the cpu will cache the line where the variable is located (the cache can be allocated The smallest cache unit) is written back to the memory. But in the case of multiple processors, after the cache line on a certain cpu is written back to the system memory, the cache of the variable on the other cpu is still old, so there will be problems when performing subsequent operations, so in order to To make the content seen by all threads consistent, it is necessary to implement the cache coherency protocol. The cpu will judge whether its cache expires by monitoring the data passed on the bus. If it expires, it needs to invalidate the cache. If the cpu When you access the cache again , you will find that the cache is invalid, and then the cache will be reloaded from memory.

Synchronized keywords:

  In addition to guaranteeing atomicity, synchronized also guarantees visibility. Because synchronized, whether it is a synchronized method or a synchronized code block, it will first copy the data in the main memory to the working memory. When the synchronized code block is completed, the data in the working memory will be updated to the main memory, so that the data in the main memory It must be the latest. More importantly, out-of-order reorganization is disabled and the writing of values ​​to the memory is guaranteed, so that visibility can be guaranteed.

Synchronized synchronization method:

The synchronization method only affects the synchronization method that locks the same lock object. It does not affect other threads to call asynchronous methods, or call other synchronization methods of lock resources.

  1. When the synchronized keyword is synchronized, the waiting thread cannot be controlled and can only die.

  2. When the synchronized keyword is synchronized, fairness is not guaranteed, so there will be threads in the queue.

synchronized Declaring methods         with keywords  has drawbacks in some cases. For example, if thread A calls a synchronous method to perform a long-time task, then thread B must wait for a long time. In this case, you can try to use  synchronized synchronous code blocks to solve the problem.

Synchronized synchronization code block:

  The synchronization granularity of the synchronization code block is more detailed, which is the recommended programming method in development. You can locate the specific synchronization location instead of simply implementing the synchronization logic of the method as a whole. In terms of efficiency, it is relatively higher.

  Wrap the code blocks that need to be synchronized, and be careful not to put time-consuming operations in synchronized code blocks. Such as print output, IO operation and so on.

Volatile keyword function

Volatile guarantees the visibility of memory data, and cannot guarantee the atomic operation of memory data

The role of synchronized keyword

Synchronized guarantees the visibility of memory data and also guarantees the atomic operation of memory data

 

Guess you like

Origin blog.csdn.net/Growing_hacker/article/details/109098523
Recommended