线程(二)---wait notify的应用场景

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!  

实现生产者消费者模型

1.创建生产者类

public class Producer implements Runnable{

    private List<Integer> container;

    public Producer(List<Integer> container){
        this.container = container;
    }

    @Override
    public void run() {
        try {
            while (true){
                produce();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void produce() throws InterruptedException{
        synchronized (container) {
            while(container.size() == 5){
                System.out.println("11111111111111111111");
                container.wait();
            }
            Integer p = new Random().nextInt(10);
            Thread.sleep(1000);
            container.add(p);
            System.out.println("生产产品:" + p);
            container.notifyAll();
        }
    }
}

  新建一个生产者类,container模拟容器大小,当container长度为5时就停止生产进入等待状态,并且会打印111111111这段话,当容器不满的时候会持续生产,生产的同时消费者也同时消费容器中的数据。

2.创建消费者类

public class Consumer implements Runnable{

    private List<Integer> container;

    public Consumer(List<Integer> container){
        this.container = container;
    }

    @Override
    public void run() {
        try {
            while (true){
                consume();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void consume() throws InterruptedException{
        synchronized (container){
            while (container.isEmpty()){
                System.out.println("2222222222222222222");
                container.wait();
            }
            Thread.sleep(1000);
            Integer product = container.remove(0);
            System.out.println("消费产品:" + product);
            container.notifyAll();
        }
    }
}

  消费者类跟生产者差不多,container模拟容器大小,当container中的数据都消费完为空时就停止消费进入等待状态,并且会打印2222这段话,当容器不为空的时候会持续消费,消费的同时生产者也同时生产。

3.创建测试类测试

public static void main(String[] args) {
        List<Integer> container = new ArrayList<>();

        Thread producer = new Thread(new Producer(container));
        producer.start();

        Thread consumer = new Thread(new Consumer(container));
        consumer.start();


}

    初始化一个容器给生产者用来存储生产的产品,消费者消费也是从这个容器中消费,启动后控制台打印如下:

为了更好的测试效果,可以启动多个生产者线程。

看网上介绍wait notify的时候除了用来实现生产者消费者模型,还提到过交替打印,也就是两个线程交替执行,

其实生产者消费者模型跟交替打印是一样的,也是生产者和消费者线程交替的执行的一种,只不过因为有容器容量的限制,不能达到真正的两个线程交替执行的效果。

上篇中已经介绍了wait()、notify()、notifyAll()是对象的方法,再补充一下,既然wait交出的是对象的控制权,notify唤醒的是等待这个对象控制权的线程,那么在使用的时候wait和notify需要注意多个线程抢夺和释放的是同一对象的控制权,synchronized锁的是同一对象。

补充一下交替打印的代码:

public static void main(String[] args) {
        List list1 = Arrays.asList(1,3,5,7,9);
        List list2 = Arrays.asList(2,4,6,8,10);
        Object obj = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < list1.size(); i++) {
                    synchronized (obj){
                        System.out.println(list1.get(i));
                        obj.notify();
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < list2.size(); j++) {
                    synchronized (obj){
                        System.out.println(list2.get(j));
                        obj.notify();
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

    }

如上:两个线程分别遍历两个集合,实现交替打印,最终打印的结果为 1,2,3.。。9.10;注意这个obj就是让两个线程操作的是同一个对象,有的地方把obj叫做是synchronized的监视器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值