多线程生产者消费者问题

生产者消费者问题

该问题需要使用线程协作和线程通讯,这是一个线程同步问题,生产者和消费者共享一个资源,并且生产者和消费者之间相互依赖互为条件
问题分析:

  1. 对于生产者,没有生产产品之前要通知消费者等待,而生产产品之后又需马上通知消费者消费。
  2. 对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品供给消费。
  3. 在生产者消费者问题中只使用synchronized是不满足的,synchronized实现同步但不能实现线程之间的通信。

关于线程通信

java提供了几个方法解决线程之间通信的问题。

方法名作用
wait()表示线程一直等待,直到其他线程通知,与sleep不同,wait会释放锁
wait(long timeout)指定等待的毫秒数
notify()唤醒一个处于等待状态的线程
notifyAll()唤醒同一个对象上所用调用wait()方法的线程,优先级高的线程优先调度

注:以上方法都是Object类的方法,都只能在同步方法或者同步代码中使用,否则会抛出异常lllegalMonitorStateException

以下给出源码

思路流程图: 本人所写代码为老师给出题目

生产者
面粉
仓库
面包
消费者

当面粉用完后停止生产,卖完所生产的面包后停止消费
生产者Producer类:

public class Producer implements Runnable{
    private Clerk clerk;
    public Producer(){}
    public Producer(Clerk clerk){
        super();
        this.clerk=clerk;
    }
    @Override
    public void run(){
        while (true){
            try{
                Thread.sleep(1000);
                clerk.produce();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

消费者Consumer类:

public class Consumer implements Runnable{
    private Clerk clerk;
    public  Consumer(){}
    public  Consumer(Clerk clerk){
        super();
        this.clerk = clerk;
    }
    @Override
    public void run(){
        while (true){
            try{
                Thread.sleep(2000);
                clerk.consume();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

店员Clerk类(操作方法类):

import java.util.LinkedList;

public class Clerk {
    // 仓库容量
    private final int MAX_SIZE = 10;
    // 仓库存储的载体
    //面粉
    private LinkedList<Object> Mianlist = new LinkedList<>();
    //馒头
    private LinkedList<Object> ManToulist = new LinkedList<>();

    public Clerk(int Mian_Counts) {
        for(int i=0;i<Mian_Counts;i++) {
            Mianlist.add(new Object());
        }

    }

    public void produce() {
        synchronized (Mianlist) {
            while(ManToulist.size() > 20) {
                System.out.println("馒头充足"+"面"+Mianlist.size());
                try {
                    Mianlist.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            while (Mianlist.size() <= 0 ) {
                System.out.println("无面粉无法继续生产馒头");
                try {
                    Mianlist.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Mianlist.remove();
            ManToulist.add(new Object());
            System.out.println("生产一个馒头,现库存的馒头" + ManToulist.size());
            Mianlist.notifyAll();
        }
    }

    public void consume() {
        synchronized (ManToulist) {
            while (ManToulist.size() == 0) {
                System.out.println("仓库里的馒头库存为空");
                try {
                    ManToulist.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            ManToulist.remove();
            System.out.println("销售一个馒头,现库存馒头" + ManToulist.size());
            ManToulist.notifyAll();
        }
    }
}

主线程类:

public class TestProduct {
    public static void main(String[] args){
        Clerk clerk = new Clerk(25);//所给面粉数量
        //生产者线程
        Thread producerThread = new Thread(new Producer(clerk));
        //消费者线程
        Thread consumerThread = new Thread(new Consumer(clerk));
        producerThread.start();
        consumerThread.start();
    }
}

小结

对于该程序本人使用了多线程学习中学到的Runnable接口,sleep()方法,线程通信的wait()方法,notifyAll()方法等,同时也使用了LinkedList链表进行面粉和馒头的增减操作。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值