并发编程之生产者消费者

从一个很经典也很基础的例子入手


生产者消费者模型,包含三个角色,分别是生产者,消费者,缓存,是一种经典的多线程场景下程序设计,好处是解耦,缓解生产消费两端的性能差,后面的各种消息队列其实都是这种思想发展而来

生产者

public class MsProducer implements Runnable{
    private ArrayList<Integer> q ;
    private Object a ;


    public MsProducer(ArrayList<Integer> q, Object a) {
        this.q = q;
        this.a = a;
    }

    @Override
    public void run() {

        int i = 0 ;
        for (;;){
            synchronized (a){
                if (q.size() >= 10){
                    try {
                        a.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                q.add(i++);
                System.out.println("生产了一个值:" + i);
                a.notify();
            }
        }
    }
}

消费者

public class MsConsumer implements Runnable{
    private ArrayList<Integer> q ;
    private Object a ;


    public MsConsumer(ArrayList<Integer> q, Object a) {
        this.q = q;
        this.a = a;
    }

    @Override
    public void run() {
        while (true){
         synchronized (a){

                if (q.size() <= 0){
                    try {
                        a.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                int t = q.remove(0);
                System.out.println("消费到一个值:" + t);
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }

             a.notify();
            }
        }
    }
}

测试代码

public class TestMain {

    public static void main(String[] args) {
        ArrayList<Integer> q = new ArrayList(10);
        Object a = new Object();

        new Thread(new MsProducer(q,a)).start();
        new Thread(new MsConsumer(q,a)).start();

    }

}

wait()和notify()是Object的方法,而不属于Thread

当一个对象实例调用wait()方法之后,当前线程就会在这个对象上等待
直到其他线程调用了notify()或者notifyAll()

notify()和notifyAll()

如果有多个线程在对象的等待队列中,notify()会从队列中随机唤醒一个线程继续执行
而notifyAll()会唤醒所有等待线程,让他们竞争到锁

wait()和notify()方法的前提都是已经获取到锁

既然wait()方法阻塞线程,释放锁,那notify()如何执行,这里隐藏的信息是,当线程在调用wait()被唤醒的时候,必须先获取到锁,再继续向下执行
举一个简单的例子:

1. 消费者取得对象锁
2. 消费者调用wait()
3. 消费者释放对象锁
消费者等待对象锁						4. 生产者取得对象锁
消费者等待对象锁						5. 生产者调用notify()
消费者等待对象锁	                    6. 生产者释放对象锁
7.消费者重新获取对象锁
8.继续执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒眉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值