Welcome to The 10th article in a series on Concurrency.
In this article, I’ll introduce you to the classic problem of concurrency, the producer-consumer problem, and use wait and notify to implement a simplified version of this problem, based on the knowledge from previous articles.
First, producer and consumer issues
The producer-consumer problem, also known as the limited-buffer problem, is a classic case of multiprocess and thread synchronization.
This problem describes what happens when two processes that share a fixed size buffer — the so-called “producer” and “consumer” — are actually running. The main role of the producer is to generate a certain amount of data to put into the buffer, and then repeat the process. At the same time, consumers consume the data in the buffer.
The key to the producer-consumer problem is to ensure that the producer does not add data when the buffer is full and the consumer does not consume data when the buffer is hollow.
To solve this problem, the producer must sleep when the buffer is full (or simply give up the data) until the next time the consumer consumes the buffer, the producer can wake up and start adding data to the buffer.
Similarly, you can have the consumer go to sleep when the buffer is empty and wake up after the producer has added data to the buffer. The method of interthread communication is usually adopted to solve this problem, such as semaphore. If the solution is not perfect, deadlock situations are likely to occur. When a deadlock occurs, both threads go to sleep, waiting for the other to wake them up.
Of course, the producer and consumer problem is not limited to a single producer and consumer, in the actual work, there are more than one producer and consumer situation.
The producer-consumer pattern is widely used in software development and design. In this pattern, producers and consumers are independent, they only pass data through the buffer, so they can be used for decoupling between programs, asynchronous peaking, etc.
Key points of producer-consumer issues:
- The producer is decoupled from the consumer, and the two pass data through the buffer;
- When the buffer is full, the producer stops data production or drops the data;
- When the buffer data is empty, the consumer stops consuming and enters a wait state, waiting for producer notification.
Second, the realization of producer and consumer programs
In this section, we simulate the producer-consumer problem through a scenario in the King.
In the king of Kings, the hero King of Lanling needs to develop by playing wild, but the wild monsters in the wild area need to be released after a period of time.
So, we created two threads, one as a producer to launch monsters into the wild and one as a consumer to fight monsters.
Producer: Check the wild area once per second, if there are no wild monsters in the wild area, then release. When the monster is released, notify the hero.
// Put the monster [producer]
public static class WildMonsterProducer implements Runnable {
public void run(a) {
try {
createWildMonster();
} catch (InterruptedException e) {
System.out.println("Troll drop interrupted."); }}// Drop monsters, check every second
public void createWildMonster(a) throws InterruptedException {
for (int i = 0;; i++) {
synchronized(wildMonsterArea) {
if (wildMonsterArea.size() == 0) {
wildMonsterArea.add("Creeps" + i);
System.out.println(wildMonsterArea.getLast());
wildMonsterArea.notify();
}
}
Thread.sleep(1000); }}}Copy the code
Consumer: Playing wild hero Lanling king as a consumer, in the wild area to fight strange development. If there are wild beasts in the wild area, knock them out. If not, wait for new monsters to be created.
// The King of Lanling fights wild heroes
public static class LanLingWang implements Runnable {
public void run(a) {
try {
attackWildMonster();
} catch (InterruptedException e) {
System.out.println("The king of Lanling's fight against the wild has been interrupted."); }}// Play wild, if not, wait
public void attackWildMonster(a) throws InterruptedException {
while (true) {
synchronized(wildMonsterArea) {
if (wildMonsterArea.size() == 0) {
wildMonsterArea.wait();
}
String wildMonster = wildMonsterArea.getLast();
wildMonsterArea.remove(wildMonster);
System.out.println("Harvester:"+ wildMonster); }}}}Copy the code
Create a field and start the producer and consumer threads.
public class ProducerConsumerProblemDemo {
// The wild area where the wild monsters live
private static final LinkedList<String> wildMonsterArea = new LinkedList<String>();
public static void main(String[] args) {
Thread wildMonsterProducerThread = new Thread(new WildMonsterProducer());
Thread lanLingWangThread = new Thread(newLanLingWang()); wildMonsterProducerThread.start(); lanLingWangThread.start(); }}Copy the code
In the code above, you need to focus on the synchronized, wait, and notify uses, which are the key to this scenario. The running results are as follows:
Nooker 0 Harvest Nooker 0 Nooker 1 Harvest Nooker: Nooker 1 Nooker 2 Harvest Nooker: Nooker 2 Nooker 3 Harvest Nooker: Nooker 3 Nooker 4 Harvest Nooker: Nooker 4 Nooker 5 Harvest Nooker: Nooker 5 Nooker 6 Harvest Nooker: Nooker 6Copy the code
As can be seen from the results, after the producer created the wild monster, the hero Lanling King would fight the wild, realizing the problem between the producer and the consumer.
summary
That’s all for thread exception handling. In this article, we solve the producer/consumer problem based on WAIT and notify. For this article, you need to understand what is at the heart of the producer-consumer issue. In addition, the solution provided in this article is only one of many solutions to this problem, and we will provide other solutions based on the new knowledge in later articles.
At the end of the text, congratulations on your another star ✨
The teacher’s trial
- Write code to implement producer and consumer issues.
read
- Producer – consumer problem
- “King concurrent course” outline and update progress overview
About the author
Pay attention to [technology 8:30], get the article updates in time. Deliver quality technical articles, 8:30 in the morning push author quality original, 20:30 in the evening push industry depth good article.
If this article is helpful to you, welcome to like, follow, supervise, we together from bronze to king.