Critical resources
A critical resource is a shared resource that is allowed to be used by only one process at a time. Each process is mutually exclusive, and the shared resources are called critical resources. Hardware belonging to critical resources include, printers, tape drives, etc;
The software includes message queue, variable, array, buffer, etc. Mutual exclusion is adopted among processes to realize the sharing of this resource.
Race condition
When two threads compete for the same resource, if they are sensitive to the access order of the resource, it is said that there is a race condition.
The code region that leads to race conditions is called the critical region. Using appropriate synchronization operations in the critical region can avoid race conditions, such as using synchronized or locking mechanisms.
Thread safety
Code that allows multiple threads to execute simultaneously is called thread safe code. Thread safe code does not contain race conditions.
Examples of thread safety problems:
When multiple threads operate on a variable at the same time, it may cause dirty reading and writing of variables (similar to mysql)
package com.company; public class Main { public static void main(String[] args) { Test test = new Test(); //Create 20 threads for (int i =1;i<=20;i++){ new Thread(()->{ for (int j =1;j<=1000;j++){ test.incA(); } },"test"+i).start(); } while(Thread.activeCount() > 2){ //main, gc, indicating that there are other threads executing Thread.yield();//Thread comity } System.out.println(Thread.currentThread().getName() + "\t int Type number Final value:" + test.a()); } } class Test{ public int a; public int a(){ return a; } public void incA(){ a++; } }
Execution results:
/Users/tioncico/Library/Java/JavaVirtualMachines/openjdk-14.0.1/Contents/Home/bin/java -javaagent:/Applications/IDE/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=56786:/Applications/IDE/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/tioncico/IdeaProjects/test/out/production/untitled104 com.company.Main main int Type number Final value: 19893
You can see that there are 20 threads * 1000 increments, but the actual value is less than 20000. This situation belongs to non thread safety
How to achieve thread safety?
volatile keyword
Through the volatile modification attribute, this attribute will directly modify the memory without internal thread caching and reordering
volatile keyword can guarantee the visibility and order of attribute operations, but it cannot guarantee atomicity
visibility
Refers to the visibility between threads. The modified state of one thread is visible to another thread. That is, when one thread modifies a shared variable, another thread can see it immediately. For example, variables modified with volatile will have visibility.
Order
Orderliness refers to the sequential execution of programs in a single threaded environment
In a multithreaded environment, program execution may be out of order due to instruction rearrangement
Instruction rearrangement
Instruction rearrangement means that the compiler and CPU may rearrange the instructions for performance
Atomicity
Sub - nature means that an operation is non - interruptible Even when multiple threads execute together,
Once an operation starts, it will not be disturbed by other threads
volatile visibility case:
package com.company; import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) { Test test = new Test(); //Create 1 thread new Thread(()->{ System.out.println(Thread.currentThread().getName() + "\t Executing"); try { TimeUnit.SECONDS.sleep(3);//Allow time for the main thread code to execute test.setA(100); System.out.println(Thread.currentThread().getName() + "\t int The value of type is:" + test.a()); } catch (InterruptedException e) { e.printStackTrace(); } },"demonstration").start(); while(test.a==0){//If it is always 0, it will always cycle } System.out.println(Thread.currentThread().getName() + "\t int Type number The value is:" + test.a()); } } class Test{ public int a=0; public int a(){ return a; } public void incA(){ a++; } public void setA(int a){ this.a = a; } }
Since there is no volatile keyword, the value obtained by the main thread is 0, so the loop will not be interrupted

Add volatile keyword:
class Test{ public volatile int a=0; public int a(){ return a; } public void incA(){ a++; } public void setA(int a){ this.a = a; } }

volatile cannot solve atomicity problems:

The main reasons are:
Thread 1 gets the value of a=0, and 0 + + becomes 1 But in fact, at the same time, threads 1-20 get the value of a=0, and + + becomes 1, which will lead to thread write coverage, and finally the value will be less than 20000;
AtomicIntegrer atomic class
Although volatile cannot achieve atomicity, it can be implemented through Java util. concurrent. Atomicinteger class} saves data and implements atomic operations:
class Test{ public AtomicInteger a = new AtomicInteger(); public int a(){ return a.get(); } public void incA(){ a.getAndIncrement(); } }
result:
/Users/tioncico/Library/Java/JavaVirtualMachines/openjdk-14.0.1/Contents/Home/bin/java -javaagent:/Applications/IDE/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=62725:/Applications/IDE/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/tioncico/IdeaProjects/test/out/production/untitled104 com.company.Main main int Type number Final value: 20000
synchronized keyword
synchronized keyword can lock a method so that it can only be accessed by one thread at a time:
class Test { public int a; public int a() { return a; } public synchronized void incA() { a++; } }
Operation results:

Reference: https://blog.csdn.net/weixin_41947378/article/details/112245369
This article is an original article of xianshike. You don't need to contact me for reprint, but please indicate that it comes from xianshike blog www.php20.com cn