1. Memory model
1.java memory model
Java memory structure means JMM (Java Memory Model). JMM defines a set of rules and guarantees for the atomicity, visibility, and orderliness of data when multi-threads read and write shared data (member variables, arrays) .
1.1 Atomicity
What is atomicity?
Atomicity means that an operation is uninterruptible. Even if multiple threads are executed together, once a thread starts, it will not be interrupted by other threads.
How to ensure atomicity
① synchronized ( synchronized keyword)
synchronized(对象){
原子操作代码
}
Starting from the first thread, locking can safely execute atomic operation code. Other threads need to wait in line
Use synchronized to solve concurrency problems
②Various Locks
synchronized and various Locks can ensure that only one thread accesses the code block at any time, thus ensuring atomicity
1.2 Visibility
What is visibility?
Visibility means that when multiple threads access the same variable, if one thread modifies the value of the variable, other threads can immediately see the modified value.
How to ensure visibility
In Java, visibility can be achieved with the help of synchronized, volatile and various Locks. If we declare a variable as volatile, this indicates to the JVM that this variable is shared and unstable and will be read from the main memory every time it is used.
volatile
Modify member variables and static member variables to prevent the thread from looking up the value of the variable from its own working cache. It must go to the main memory to obtain its value. When threads operate volatile variables, they directly operate the main memory .
1.3 Orderliness
What is orderliness?
①Due to the problem of instruction reordering, the execution order of the code may not be the order when the code is written.
② Instruction reordering can ensure consistent serial semantics, but there is no obligation to ensure that the semantics between multiple threads are also consistent, so under multi-threading, instruction reordering may cause some problems.
③In Java, the volatile keyword can prohibit instructions from being reordered and optimized.
2.happens-before
introduce
happens-before specifies which write operations are visible to read operations from other threads . is a set of rules for visibility and order .
How to guarantee
①volatile
②synchronized
2. CAS and atomic classes
1. Overview of CAS lock-free concurrency
1. Introduction
①The full name of CAS is compare and swap.
②When multiple threads operate the same resource at the same time , only one thread can operate successfully . But other threads will not be blocked, and other threads will only receive a signal that the operation failed.
③CAS is an optimistic lock
Replenish
Optimistic locking : It is believed that data will not conflict under normal circumstances, so when the data is submitted for update, it will detect whether the data has concurrency conflicts. If a concurrency conflict is found, an error message will be returned. The returned error message can be based on your own business to be processed
Pessimistic lock: Always assume the worst case scenario. Every time you get shared data, you think others will modify it, so you lock it every time you get the data. Shared resources will only be used by one thread at a time, other threads will be blocked, and then the resources will be given to other threads after use.
2. Workflow
Read and write memory value V
The value A to compare with
The new value B that needs to be written
①The original data V in the memory, the old value A, and the modified new value B.
② Compare A and V to see if they are equal
③If equal, write B into V ( exchange )
④Return whether the operation is successful
3. Code analysis
Multiple threads perform +1 operation on a shared integer variable
①CAS does not lock, use while(true) infinite loop regardless of attempts/
② Shared variables are read from memory, so the visibility of the variables is guaranteed . Use volatile modification
③Call compareAndSwap(old value, new value) for comparison.
④The compareAndSwap operation is successful and the loop exits .
⑤The compareAndSwap operation fails , indicating that other threads have modified this shared variable. Need to read in loop again
Notice:
①CAS and volatile are combined to achieve lock-free concurrency, suitable for low competition and multi-core CPUs (loop retry)
② Competition is fierce and retries occur frequently, reducing efficiency.
③ If synchronized is not used, the thread will not be blocked and efficiency will be improved.
4. Disadvantages of CAS
① ABA problem . During the CAS update operation, check whether the memory value has changed. If there is no change, update the memory value. If the original memory value is A, then it changes to B, and then changes back to A again. There is an ABA problem, there is no change in the CAS check, but there is an actual change . The solution is to add a version number in front of the variable , and add 1 to the version number each time it is updated. This changes to 1A2B3A
②The cycle time is long and the cost is high. If the CAS operation is unsuccessful for a long time, it will cause a continuous loop. High CPU overhead
③Only atomic operation of one shared variable is guaranteed. When performing an operation on a shared variable, CAS can guarantee the atomic operation, but when operating on multiple shared variables, CAS cannot guarantee the atomicity of the operation.
2. CAS underlying implementation
introduce
The bottom layer of CAS relies on an Unsafe class to directly call the CAS instructions at the bottom of the operating system.
Call the CAS method in the UnSafe class, and the JVM will help us implement the CAS assembly instructions
Part of the code
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
Parameter Description
thisUnsafeObject _
valueOffsetThe address of the shared variable
expect old value
update new value
If the value in the atomic variable is equal to expect, update the value with the update value and return true, otherwise return false.
3. Atomic operation class
juc provides atomic operation classes that can provide thread-safe operations. AtomicInteger,AtomicBoolean. The underlying implementation is CAS+volatile implementation