Detailed explanation of the implementation principle of Java Concurrent waiting condition
preface
The implementation mechanism of exclusive lock and shared lock was introduced earlier. This article continues to learn another content in AQS - condition. Anyone who has studied Java must know object Wait and object Notify, and you should also know that the use of these two methods is inseparable from the synchronized keyword. Synchronized is a synchronization primitive provided at the JVM level, and its implementation mechanism is hidden in the JVM implementation. As a condition in the lock series of functions, it is used to implement similar objects Wait and object The corresponding function of notify.
Usage scenario
In order to better understand the use scenarios of lock and condition, let's first implement such a function: there are multiple producers, multiple consumers and a product container. We assume that the container can hold up to three products. If it is full, the producer needs to wait for the product to be consumed. If there are no products, the consumer needs to wait. Our goal is to produce a total of 10 products and eventually consume 10 products. How to complete this challenge in a multithreaded environment? The following is a demo of my simple implementation, for reference only.
The results of one execution are as follows:
From the results, we can find that our goal has been achieved.
Deeply understand the implementation principle of condition
The above example is just to show a classic scenario that lock and condition can achieve. After having a perceptual understanding, we will observe step by step how lock and condition cooperate to complete this task, which is also the core content of this article.
In order to better understand and demonstrate this process, the lock we use uses the fair policy mode. We will use the process of the above example. We will use three production threads and three consumption threads, representing P1, P2, P3 and C1, C2 and C3 respectively.
The internal implementation of condition is implemented by node chain. Each condition instance corresponds to a node chain. We have two condition instances, notempty and notfull, so there will be two waiting node chains.
Everything is ready to start our journey of exploration.
1. Thread C3 executes and finds that no product can be consumed. Execute notempty Await, enter the waiting queue and wait.
2. Thread C2 and thread C1 execute, and then find that no product can be consumed, execute notempty Await, enter the waiting queue and wait.
3. Thread P1 starts and gets the lock. P1 starts to produce products. At this time, P3 preempts P2 and performs the lock operation. As a result, P2 and P3 are in the waiting state and enter the synchronization queue to wait< "/ KF / ware / VC /" target = "_blank" class = "keylink" > vcd4ncjxwpjxpbwcgywx0pq = = "write picture description here" SRC = "/ UploadFile / colfiles / 20160912 / 20160912092710536. PNG" title = "\" / >
Note that in this example, we use the exclusive lock in the fair policy mode. Since P3 preempts the lock taking operation, although P2 and P3 are blocked, P3 will be awakened first.
4. This will cause P1 to complete production, notify not empty of the waiting queue, wake up a waiting thread node, and then release the lock. Releasing the lock will cause P3 to be awakened, and then P1 will enter the next cycle and enter the synchronization queue.
Things began to get interesting. After P1 performed a production, it performed notempty The effect of signal is to move the head node in the not empty waiting list, that is, C3 node, to the synchronous waiting queue and re participate in the preemption lock.
5. After P3 finished producing the product, continue notempty Signal and release the lock at the same time. After releasing the lock, P2 thread will wake up, and P3 will join the queue again when trying to obtain the lock in the next round.
6. Then, P2 continue production and execute notempty Signal, release the lock at the same time, wake up the C3 thread after releasing the lock, and then P2 enter the column when trying to take the lock in the next round.
7. C3 for consumption, you can see that there are no waiting nodes in the not empty waiting queue. Because we use the fair policy exclusive lock, it will cause the nodes in the synchronization queue to execute one by one. At present, the nodes in the synchronization queue are arranged as one production and one consumption, which is not difficult to know, Next, the code will not enter the wait condition, so it will be executed one by one. For example, C3, after execution, continue notfull signal(); Then release the lock and join the team. Understand here, not full signal(); This code doesn't work because there are no waiting thread nodes in the not full waiting queue. After C3 is executed, the status is shown in the following figure:
8. I think everyone can figure out how to carry out the latter things alternately step by step.
summary
Based on an example, this article demonstrates how to realize the production consumption mode by combining lock and condition, and only discusses one possible process. It wants to more simply describe how to realize the bottom layer of AQS. Based on the above demonstration process, it is the same for other execution processes. Condition uses a node chain to store all threads in wait status. When the corresponding condition is signaled, it will transfer the waiting node to the synchronization queue and continue to compete for locks. The principle is not complicated. Interested friends can read the source code.
The above is all about the detailed explanation of the implementation principle of Java Concurrent waiting conditions in this paper. I hope it will be helpful to you. Interested friends can continue to refer to this site: detailed explanation of BlockingQueue for Java Concurrent learning to realize producers and consumers, detailed explanation of nested pipe locking of Java concurrency, detailed explanation of high concurrency solutions of Java system, etc. if there are any problems, you can leave a message at any time, and the editor will reply to you in time. Thank you for your support!