Problema productor-consumidor de comunicación entre hilos

Problema del consumidor productor

Este es un problema de sincronización de hilos: productores y consumidores comparten el mismo recurso, y productores y consumidores dependen unos de otros como condiciones.

◆ Para el productor, antes de producir el producto, se debe notificar al consumidor que espere. Después de que se produce el producto, el consumidor debe ser notificado inmediatamente.
◆ Para el consumidor, después del consumo, se debe notificar al productor que el consumo ha terminado y la necesidad de producir nuevos Productos para consumo
◆ En el problema productor-consumidor, sincronizar por sí solo no es suficiente.
Sincronizado puede evitar actualizaciones simultáneas del mismo recurso compartido. Se logra la sincronización. Sincronizado
no puede usarse para lograr la transferencia de mensajes (comunicación) entre diferentes hilos.

Java proporciona varios métodos para resolver el problema de comunicación entre subprocesos, lo que
wait() significa que el subproceso espera hasta que otros subprocesos notifiquen. A diferencia de la suspensión, el bloqueo se liberará.
wait(long timeout)Especifica el número de milisegundos de espera.
notify()Activa un hilo en un estado de espera.
notifyAll()Activa todos los hilos que llaman al método wait () en el mismo objeto. El hilo con mayor prioridad se programa primero.

Nota: Todos los métodos de la clase Oject solo se pueden usar en métodos síncronos o bloques de código síncronos; de lo
contrario , se lanzará una excepción IIIegalMonitorStateException

Solución 1:
Modelo de colaboración concurrente "modo productor / consumidor" -> método de gestión
Productor: el módulo responsable de producir datos
Consumidor: admite el
búfer del módulo para procesar datos : Los consumidores no pueden utilizar directamente los datos del productor, Hay una zona de amortiguamiento entre ellos. Es decir, el productor coloca los datos producidos en el búfer y el consumidor saca los datos del búfer.

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;
    }
}

Solución 2: método de luz de señal

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;
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_42524288/article/details/105839553
Recomendado
Clasificación