Consumer producer (Java implementation)

Consumer producer (Java implementation)

Overview


The producer consumer, as the name implies, the consumer consumes what the producer produces.

How to understand it in Java code?

We call a method to change the shared variable, which is the medium of communication between multiple threads.

It can also be understood that our thread is the execution of our code. If the execution of the A thread requires the support of the B thread or a certain dependency, then we need to communicate between the two threads. The A thread will notify the B thread after it changes the shared variable. Similarly, thread B notifies thread A after changing the shared variable.


Management method implementation

We use code to achieve (management method: define a shared pool, when there are multiple shared variables)


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;

    }
}

Semaphore method

If our shared variable is a mutual exclusion lock, that is, there is only one shared variable, we can use an identifier as a medium for thread communication.

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

Guess you like

Origin blog.csdn.net/qq_44112474/article/details/108567698