01 | Visibility, atomicity, and ordering: the source of concurrent programming bugs
The story behind the concurrent program
One of the sources: Visibility issues caused by caching
The second source: the atomic problem caused by thread switching
The third source: the ordering problem brought by compilation optimization
to sum up
02 | Java Memory Model: See how Java solves the problems of visibility and order
What is the Java memory model?
Confusion about using volatile
Happens-Before rule
The result of the previous operation is visible to subsequent operations
-
The sequence rule of the program
This rule refers to the previous operation Happens-Before in any thread in accordance with the sequence of the program in a thread. -
Volatile variable rule
This rule refers to the write operation of a volatile variable, Happens-Before in the subsequent read operation of this volatile variable. -
Transitivity
This rule means that if A Happens-Before B and B Happens-Before C, then A Happens-Before C. -
The rule of lock in the pipe process
This rule refers to the unlocking of a lock Happens-Before and subsequent locking of this lock. -
Thread start () rule
This is about thread start. It means that after the main thread A starts the child thread B, the child thread B can see the operation of the main thread before starting the child thread B. -
Thread join () rule
This is about thread waiting. It means that the main thread A waits for the sub-thread B to complete (the main thread A is realized by calling the sub-thread B's join () method), and when the sub-thread B completes (the main thread A's join () method returns), the main thread can see To the child thread. Of course, the so-called "see" refers to the operation of shared variables.
to sum up
In the Java language,The semantics of Happens-Before is essentially a kind of visibility, A Happens-Before B means that the A event is visible to the B event, regardless of whether the A event and the B event occur in the same thread. For example, the A event occurs on thread 1, and the B event occurs on thread 2. The Happens-Before rule ensures that thread 2 can also see the occurrence of event A.
03 | Mutual Exclusion Lock (Part 1): Solving Atomic Problems
How to solve the atomic problem?
You already know that the source of the atomicity problem is
that the condition of thread switching "only one thread executes at the same time" is very important, which we call mutual exclusion.
Simple lock model
Improved lock model
Lock technology provided by Java language: synchronized
04 | Mutual Exclusion Lock (Part 2): How to protect multiple resources with one lock?
Protect multiple resources that are not related
Protect multiple resources that are related
to sum up
What is the essence of "atomicity"? In fact, it is not indivisible, indivisible is just an external manifestation, its essence is the requirement of consistency among multiple resourcesThe intermediate state of the operation is not visible to the outside world.
05 | What to do if I deadlock accidentally?
How to prevent deadlock
- Destroy occupancy and wait conditions
- Destruction of non-preemptible conditions
- Break the loop wait condition
06 | Optimized circular waiting with "wait-notify" mechanism
Implementing wait-notify mechanism with synchronized
07 | Security, activity and performance issues
Does all the code need to be carefully analyzed whether these three problems exist? Of course not. In fact, only one situation is needed: there is shared data and the data will change. Generally speaking, multiple threads will read and write the same data at the same time.
Concurrent programmingThere are many issues that we need to pay attention to. Fortunately, our predecessors have helped us summarize them. There are three main aspects, namely: security issues, active issues, and performance issues.
Security issues
When multiple threads access the same data at the same time, and at least one thread will write this data, if we do not take protective measures, it will lead to concurrent bugs. There is also a professional term for this, called data race (Data Race) )
Race condition refers to the order in which the execution result of the program depends on the thread execution.
Faced with data competition and race conditions , how can we ensure thread safety? In fact, both types of problems can use the mutual exclusion technology solution, and there are many solutions to achieve mutual exclusion. The CPU provides related mutually exclusive instructions, and the operating system and programming language also provide related APIs. From a logical point of view, we can be unified into: lock .
Active problem
The so-called liveness problem refers to that an operation cannot be performed. Our common "deadlock" is a typical active problem, of course, in addition to deadlock , there are two cases, namely " livelock " and "hunger" .
Sometimes although the thread is not blocked, there will still be situations where it cannot be executed. This is called "live lock".
The so-called "hunger" refers to the situation that the thread cannot execute because it cannot access the required resources.
Performance issues
The reason why there are so many things in the Java SDK concurrent package is that a large part of the reason is to improve performance in a specific field.
to sum up
08 | Governance: the master key for concurrent programming
What is control
MESA model
The correct posture of wait ()
notify () when can it be used
to sum up
09 | Java Thread (Part 1): Java Thread Life Cycle
Common thread life cycle
Thread life cycle in Java
-
RUNNABLE and BLOCKED state transition
There is only one scenario that will trigger this transition, that is, the thread waits for an implicit lock synchronized -
The state transition of RUNNABLE and WAITING The
first scenario is to obtain a synchronized implicit lock thread and call the parameterless Object.wait () method.
The second scenario is to call the parameterless Thread.join () method.
In the third scenario, call the LockSupport.park () method. Call the LockSupport.park () method, the current thread will block, and the state of the thread will change from RUNNABLE to WAITING. Call LockSupport.unpark (Thread thread) to wake up the target thread, and the state of the target thread will change from WAITING state to RUNNABLE. -
RUNNABLE and TIMED_WAITING state transition
-
From NEW to RUNNABLE state, call the start () method of the thread object
-
From RUNNABLE to TERMINATED state
What is the main difference between the stop () and interrupt () methods?
10 | Java threads (middle): How many threads are appropriate to create?
Why use multithreading?
There are many indicators to measure performance, but there are two indicators at the core, which are latency and throughput .
Multi-threaded application scenarios
How many threads are appropriate to create?
CPU-intensive computing scenarios, in theory, "the number of threads = the number of CPU cores" is the most appropriate. However, in engineering, the number of threads is generally set to "CPU cores + 1"
For I / O-intensive computing scenarios, the optimal number of threads = number of CPU cores * [1 + (I / O time-consuming / CPU time-consuming)]
In fact, as long as you grasp a principle, this principle is to maximize the performance of the hardware.
11 | Java Threads (Part 2): Why are local variables thread-safe?
How the method is executed
Where are local variables stored?
Call stack and thread
Thread closure
12 | How to write concurrent programs with object-oriented thinking?
First, encapsulate shared variables
For these shared variables that will not change, it is recommended that you use the final keyword to modify
Second, identify the constraints between shared variables
3. Develop concurrent access strategies
13 | Answers to hot issues of theoretical foundation modules
What about this "serial story"?