Productor de consumidores (implementación de Java)

Productor de consumidores (implementación de Java)

Visión general


El consumidor productor, como su nombre lo indica, el consumidor consume lo que produce el productor.

¿Cómo entenderlo en código Java?

Llamamos a un método para cambiar la variable compartida, que es el medio de comunicación entre múltiples hilos.

También se puede entender que nuestro hilo es la ejecución de nuestro código. Si la ejecución del hilo A requiere el soporte del hilo B o una cierta dependencia, entonces necesitamos comunicarnos entre los dos hilos. El hilo A notificará al hilo B después de que cambie la variable compartida. De manera similar, el hilo B notifica al hilo A después de cambiar la variable compartida.


Implementación del método de gestión

Usamos código para lograr (método de gestión: definir un grupo compartido, cuando hay múltiples variables compartidas)


package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 01:41
 * @Decription: 实现生产者消费者问题1(管程法)
 **/
public class TestPC1 {
    
    
    public static void main(String[] args) {
    
    
        // 只有一个鸡池,保证synchronized锁的同一个对象
        ChickenPool chickenPool = new ChickenPool();
        new Product(chickenPool).start();
        new Consumer(chickenPool).start();

    }
}

// 生产者
class Product extends Thread {
    
    
    ChickenPool chickenPool;

    public Product(ChickenPool chickenPool) {
    
    
        this.chickenPool = chickenPool;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            try {
    
    
                chickenPool.push(new Chicken(i));
                System.out.println("投放了第" + i + "只鸡");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

// 消费者
class Consumer extends Thread {
    
    
    ChickenPool chickenPool;

    public Consumer(ChickenPool chickenPool) {
    
    
        this.chickenPool = chickenPool;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            try {
    
    
                Chicken pop = chickenPool.pop();
                System.out.println("吃了第" + pop.id + "只鸡");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

// 鸡腿
class Chicken {
    
    
    int id;

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

// 缓冲区
class ChickenPool {
    
    

    Chicken[] chickens = new Chicken[10];
    int index = 0;

    // 生产鸡
    public synchronized void push(Chicken chicken) throws InterruptedException {
    
    
        // 如果池子满了就等待消费
        if (index >= chickens.length) {
    
    
            this.wait();
        }
        chickens[index] = chicken;
        index++;
        // 如果生产鸡了就通知消费
        this.notifyAll();

    }

    // 消费鸡
    public synchronized Chicken pop() throws InterruptedException {
    
    
        // 如果没鸡了就等待生产鸡
        if (index <= 0) {
    
    
            this.wait();
        }
        index--;
        Chicken chicken = chickens[index];
        TimeUnit.MILLISECONDS.sleep(1000);
        // 如果鸡吃完了就通知生产
        this.notifyAll();
        return chicken;

    }
}

Método del semáforo

Si nuestra variable compartida es un bloqueo de exclusión mutua, es decir, solo hay una variable compartida, podemos usar un identificador como medio para la comunicación del hilo.

package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 02:54
 * @Decription:
 **/
public class TestPC2 {
    
    
    public static void main(String[] args) {
    
    
        TV tv= new TV();
        new Actor(tv).start();
        new Watch(tv).start();
    }
}
// 演员
class Actor extends Thread{
    
    
    TV tv;
    public Actor(TV tv){
    
    
        this.tv = tv;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            // 为了节目效果,交替执行
            if (i % 2 == 0){
    
    
                try {
    
    
                    this.tv.play("剥夺结衣"+i);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }else {
    
    
                try {
    
    
                    this.tv.play("仓老师"+i);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}
// 观众
class Watch extends Thread{
    
    
    TV tv;
    public Watch(TV tv){
    
    
        this.tv = tv;
    }

    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            try {
    
    
                this.tv.watch();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}
// 电视
class TV{
    
    
    String tvName ;
    boolean flag = true;  // 演员是否需要表演

    // 表演节目
    public synchronized void play(String tvName) throws InterruptedException {
    
    

        if (!flag){
    
    
            this.wait();
        }else {
    
    
            System.out.println("演员表演了"+tvName);
            this.notifyAll();
            this.flag = !this.flag;
            this.tvName = tvName;
            TimeUnit.SECONDS.sleep(1);
        }
    }

    // 看节目
    public synchronized void watch() throws InterruptedException {
    
    
        if (flag){
    
    
            this.wait();
        }else {
    
    
            System.out.println("观众看了"+this.tvName);
//            TimeUnit.SECONDS.sleep(1);
            this.notifyAll();
            this.flag = !this.flag;
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_44112474/article/details/108567698
Recomendado
Clasificación