• 线程通信的应用:经典例题:生产者/消费者问题


    /**
    * 线程通信的应用:经典例题:生产者/消费者问题
    *
    * 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,
    * 店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员
    * 会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品
    * 了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
    *
    * 分析:
    * 1. 是否是多线程问题?是,生产者线程,消费者线程
    * 2. 是否有共享数据?是,店员(或产品)
    * 3. 如何解决线程的安全问题?同步机制,有三种方法
    * 4. 是否涉及线程的通信?是
    *
    */
    class Clerk{

    private int productCount = 0;
    //生产产品
    public synchronized void produceProduct() {

    if(productCount < 20){
    productCount++;
    System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount + "个产品");

    notify();

    }else{
    //等待
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }
    //消费产品
    public synchronized void consumeProduct() {
    if(productCount > 0){
    System.out.println(Thread.currentThread().getName() + ":开始消费第" + productCount + "个产品");
    productCount--;

    notify();
    }else{
    //等待
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }
    }

    class Producer extends Thread{//生产者

    private Clerk clerk;

    public Producer(Clerk clerk) {
    this.clerk = clerk;
    }

    @Override
    public void run() {
    System.out.println(getName() + ":开始生产产品.....");

    while(true){

    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    clerk.produceProduct();
    }

    }
    }

    class Consumer extends Thread{//消费者
    private Clerk clerk;

    public Consumer(Clerk clerk) {
    this.clerk = clerk;
    }

    @Override
    public void run() {
    System.out.println(getName() + ":开始消费产品.....");

    while(true){

    try {
    Thread.sleep(20);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    clerk.consumeProduct();
    }
    }
    }

    public class ProductTest {

    public static void main(String[] args) {
    Clerk clerk = new Clerk();

    Producer p1 = new Producer(clerk);
    p1.setName("生产者1");

    Consumer c1 = new Consumer(clerk);
    c1.setName("消费者1");
    Consumer c2 = new Consumer(clerk);
    c2.setName("消费者2");

    p1.start();
    c1.start();
    c2.start();

    }
    }
  • 相关阅读:
    移动函数的封装示例
    如何从不均衡类中进行机器学习
    DPM(Deformable Parts Model)--原理(一)
    K-means聚类算法
    机器学习中对核函数的理解
    总结:Bias(偏差),Error(误差),Variance(方差)及CV(交叉验证)
    技术干货
    神经网络入门
    目标函数、损失函数、代价函数
    地铁客流检测训练问题记录
  • 原文地址:https://www.cnblogs.com/terrycode/p/12359969.html
Copyright © 2020-2023  润新知