Producer and consumer issues
The producer-consumer problem (English: Producer-consumer problem), also known as the bounded-buffer problem (English: Bounded-buffer problem), is a classic case of multi-process synchronization problems. This problem describes what happens when two processes sharing a fixed-size buffer -the so-called "producer" and "consumer"-actually run. The main role of the producer is to generate a certain amount of data into the buffer, and then repeat the process. At the same time, consumers are consuming these data in the buffer. The key to this problem is to ensure that producers will not add data when the buffer is full, and consumers will not consume data when the buffer is empty.
1.1Mechanism provided by java
All are methods in the Object class, and they can only be used in synchronous methods and synchronous code blocks.
void |
notify() Wake up a single thread waiting on the monitor of this object. |
---|---|
void |
notifyAll() Wake up all threads waiting on this object monitor. |
void |
wait() Makes the current thread wait for another thread calls this method or object method.notify() notifyAll() |
---|---|
void |
wait(long timeout) Makes the current thread wait for another thread calls this method or object method, or a specified time elapses.notify() notifyAll() |
void |
wait(long timeout, int nanos) Makes the current thread wait for another thread calls this method or object method, or some other thread interrupts the current thread, or a certain amount of real time has passed.notify() notifyAll() |
1.2 Provide buffer
/**
* 管程法解决生产者消费者问题
*/
public class TestBuffer {
public static void main(String[] args) {
//创建缓冲区
BufferSynContainer container = new BufferSynContainer();
new Producer(container).start();
new Consumer(container).start();
}
}
class Producer extends Thread{
BufferSynContainer buffer;
public Producer(BufferSynContainer buffer){
this.buffer = buffer;
}
//生产
public void run() {
for (int i = 0; i < 100; i++) {
buffer.push(new Chicken(i+1));
System.out.println("生产了"+(i+1)+"只鸡");
}
}
}
class Consumer extends Thread{
BufferSynContainer buffer;
public Consumer(BufferSynContainer buffer){
this.buffer = buffer;
}
//消费
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了-->"+buffer.pop().getId()+"只鸡");
}
}
}
//产品
class Chicken{
private int id;
public Chicken(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
class BufferSynContainer{
//缓冲区大小
Chicken[] chickens = new Chicken[10];
int count = 0;
//生产者生产
public synchronized void push(Chicken chicken){
//容器满了,生产者等待
if (count==chickens.length){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//放入缓冲区
chickens[count] = chicken;
count++;
//通知消费者可以消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//看缓冲区中是否有数据
if (count<=0){
try {
this.wait();//没有产品等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有数据进行消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}
1.3 Semaphore method-concurrent collaboration
semaphore mutex = 1;
2 semaphore fillCount = 0;
3 semaphore emptyCount = BUFFER_SIZE;
4
5 procedure producer() {
6 while (true) {
7 item = produceItem();
8 down(emptyCount);
9 down(mutex);
10 putItemIntoBuffer(item);
11 up(mutex);
12 up(fillCount);
13 }
14 }
15 procedure consumer() {
16 while (true) {
17 down(fillCount);
18 down(mutex);
19 item = removeItemFromBuffer();
20 up(mutex);
21 up(emptyCount);
22 consumeItem(item);
23 }
24 }