多线程经典案例-生产者与消费者

1.案例分析

生产者消费者问题,包含了两类线程:

  • 一类是生产者线程用于生产数据
  • 一类是消费者线程用于消费数据

可以让生产者与消费者共享同一个数据区域(类似一个仓库,容量为1)。
生产者生产数据后放入数据共享区,并不需要知道消费者做的事情。
消费者从数据共享区获取数据,也并不需要知道生产者做的事情。

2.案例实现

容器类(Box):提供存储数据和获取数据的操作
生产者类(Producer):实现Runnable接口,重写run()方法,调用存储数据的操作
消费者类(Customer):实现Runnable接口,重写run()方法,调用获取数据的操作
测试类(Test)

2.1 Box类

public class Box{
    //定义state用来判断数据共享区是否有数据
    private boolean state=false;

    //定义取数据方法
    public synchronized void put(){
        //判断数据共享区是否有数据
        if (state){
            try {
                //有数据则进行等待,直到消费者进程取出数据进程并唤醒该进程
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //执行到此处,说明进程被唤醒(此时数据共享区无数据)
        //用输出语句模拟数据的生产过程
        System.out.println("生产者已生产出需要的数据,可以进行使用!");
        //数据生产完成,修改state,表示数据共享区有数据
        state=true;
        //唤醒消费者线程消费数据
        notifyAll();
    }

    public synchronized void get(){
        if (!state){
            try {
                //数据共享区无数据,进程等待,直到生产者线程生产数据并唤醒该进程
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //执行到此处,说明进程被唤醒(此时数据共享区有数据)
        //用输出语句模拟数据的取出过程
        System.out.println("数据已被取出使用,请尽快生产数据!");
        //数据取出,修改state,表示数据共享区无数据
        state=false;
        //唤醒生产者线程生产数据
        notifyAll();
    }
}

2.2 Producer(生产者)类

public class Producer implements Runnable{
    private Box b;

    public Producer(Box b) {
        this.b = b;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            b.put();
        }
    }
}

2.3 Customer(消费者)类

public class Customer implements Runnable{
    private Box b;

    public Customer(Box b) {
        this.b = b;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            b.get();
        }
    }
}

2.4 Test(测试)类

public class Test {
    public static void main(String[] args) {
        //创建Box对象,这是数据共享区
        Box b=new Box();
        //创建生产者对象,把Box对象作为构造方法的参数传递进去
        //在生产者类中要调用生产数据的操作
        Producer p=new Producer(b);
        //创建消费者对象,把Box对象作为构造方法的参数传递进去
        //在消费者类中要调用使用数据的操作
        Customer c=new Customer(b);
        //创建两个线程对象,分别把生产者对象和消费者对象作为构造方法的参数传递进去
        Thread t1=new Thread(p);
        Thread t2=new Thread(c);
        //启动线程
        t1.start();
        t2.start();
    }
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值