Producer-consumer problem of communication between threads

Producer consumer problem

This is a thread synchronization problem. Producers and consumers share the same resource, and the producers and consumers depend on each other as conditions.

◆For the producer, before producing the product, the consumer must be notified to wait. After the product is produced, the consumer needs to be notified immediately.
◆For the consumer, after the consumption, the producer must be notified that the consumption has ended and the need to produce new Products for consumption
◆In the producer-consumer problem, synchronized alone is not enough.
Synchronized can prevent concurrent updates of the same shared resource. Synchronization is achieved. Synchronized
cannot be used to achieve message transfer (communication) between different threads.

Java provides several methods to solve the communication problem between threads, which
wait() means that the thread waits until other threads notify. Unlike sleep, the lock will be released.
wait(long timeout)Specify the number of milliseconds to wait.
notify()Wake up a thread in a waiting state.
notifyAll()Wake up all threads that call the wait() method on the same object. The thread with higher priority is scheduled first.

Note: All methods of the Oject class can only be used in synchronous methods or synchronous code blocks,
otherwise an exception IIIegalMonitorStateException will be thrown

Solution 1:
Concurrent collaboration model "producer/consumer mode"—>management method
Producer: the module responsible for producing data
Consumer: support the module
buffer for processing data : Consumers cannot directly use the producer’s data, There is a buffer zone between them. That is, the producer puts the produced data into the buffer, and the consumer takes out the data from the buffer.

package com.lu.gaoji;

//测试:生产者消费者模型-->利用缓冲区解决:管程法
//生产者、消费者、产品、缓冲区
public class TestPC {
    
    
    public static void main(String[] args) {
    
    
        SynContainer container = new SynContainer();

        new Productor(container).start();
        new Consumer(container).start();
    }
}

//生产者
class Productor extends Thread{
    
    
    SynContainer container;

    public Productor(SynContainer container){
    
    
        this.container = container;
    }

    //生产
    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("生产了" + i + "只鸡");
            container.push(new Chicken(i));
        }
    }
}

//消费者
class Consumer extends Thread{
    
    
    SynContainer container;

    public Consumer(SynContainer container){
    
    
        this.container = container;
    }

    //消费
    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("消费了-->"+container.pop().id+"只鸡");
        }
    }
}

//产品
class Chicken{
    
    
    int id; //产品编号

    public Chicken(int id) {
    
    
        this.id = id;
    }
}

//缓冲区
class SynContainer{
    
    
    //需要一个容器
    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;
    }
}

Solution 2: Signal light method

package com.lu.gaoji;

//测试生产者消费者问题2:信号灯法。标志位解决
public class TestPC2 {
    
    
    public static void main(String[] args) {
    
    
        TV tv = new TV();

        new Player(tv).start();
        new Watcher(tv).start();
    }
}

//生产者-->演员
class Player extends Thread{
    
    
    TV tv = new TV();

    public Player(TV tv) {
    
    
        this.tv = tv;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            if (i%2 == 0){
    
    
                tv.play("快乐大本营播放");
            }else {
    
    
                tv.play("抖音");
            }
        }
    }
}

//消费者-->观众
class Watcher extends Thread{
    
    
    TV tv = new TV();

    public Watcher(TV tv) {
    
    
        this.tv = tv;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            tv.watch();
        }
    }
}

//产品-->节目
class TV{
    
    
    //演员表演时,观众等待
    //观众观看是,演员等待
    String voice; //表演的节目
    boolean flag = true;

    //表演
    public synchronized void play(String voice){
    
    
        if (!flag){
    
    
            try {
    
    
                this.wait();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了:"+voice);
        //通知观众观看
        this.notifyAll();//通知唤醒
        this.voice = voice;
        this.flag = !flag;
    }

    //观看
    public synchronized void watch(){
    
    
        if (flag){
    
    
            try {
    
    
                this.wait();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        System.out.println("观众观看了:"+voice);
        //通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}

Guess you like

Origin blog.csdn.net/qq_42524288/article/details/105839553