zoukankan      html  css  js  c++  java
  • 通过生产者消费者模式例子讲解Java基类方法wait、notify、notifyAll

    wait(),notify()和notifyAll()都是Java基类java.lang.Object的方法。

    通俗解释
    wait():在当前线程等待其它线程唤醒。
    notify(): 唤醒一个线程正在等待这个对象的监视器。
    notifyAll(): 唤醒在这个对象监视器上等待的所有线程。
    这三个方法,都是Java语言提供的实现线程间阻塞(Blocking)和控制进程内调度(inter-process communication)的底层机制。
    下面通过一个生产者/消费者的例子来讲解这三个方法的使用

    /**
     * 消费者
     * Created by Wiki on 16/1/28.
     */
    public class Customer implements Runnable {
        private String name;
        private Channel channel;
    
        public Customer(String name, Channel channel) {
            this.name = name;
            this.channel = channel;
        }
    
        @Override
        public void run() {
            while (true) {
                Good good = channel.get();
                if (good != null) {
                    System.out.println(name + " 获得商品:" + good.getName());
                } else {
                    synchronized (channel) {
                        try {
                            System.out.println(name + " 进入等待");
                            channel.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    /**
     * 生产者
     * Created by Wiki on 16/1/28.
     */
    public class Producer implements Runnable {
        private static volatile int goodNumber = 0;
    
        private String name;
        private Channel channel;
    
        public Producer(String name, Channel channel) {
            this.name = name;
            this.channel = channel;
        }
    
        @Override
        public void run() {
            while (true) {
                int sleep = new Random().nextInt(2000);
                try {
                    Thread.sleep(sleep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Good good = new Good("商品-编号" + (++goodNumber));
                System.out.println(name + " 生产商品:" + good.getName());
                channel.put(good);
            }
        }
    }
    /**
     * 商品
     * Created by Wiki on 16/1/28.
     */
    public class Good {
        private String name;
    
        public Good(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    /**
     * 消费通道
     * Created by Wiki on 16/1/28.
     */
    public class Channel {
        private Queue<Good> goodList = new LinkedList<>();
    
        public synchronized Good get() {
            if (goodList.size() == 0) {
                return null;
            }
            Good good = goodList.remove();
            return good;
        }
    
        public synchronized void put(Good good) {
            goodList.add(good);
    //        notifyAll();
            notify();
        }
    }
    public class Main {
    
        public static void main(String[] args) {
            Channel channel = new Channel();
            new Thread(new Producer("生产者1", channel)).start();
            new Thread(new Producer("生产者2", channel)).start();
            new Thread(new Producer("生产者2", channel)).start();
    
            new Thread(new Customer("消费者1", channel)).start();
            new Thread(new Customer("消费者2", channel)).start();
            new Thread(new Customer("消费者3", channel)).start();
        }
    }

    运行结果分析一(notify):

    每次生产一个商品调用notify时,都只唤醒一个消费者进行消费,唤醒原则是从等待时间最长的开始。

    消费者1 进入等待
    消费者2 进入等待
    消费者3 进入等待
    生产者1 生产商品:商品-编号1
    消费者1 获得商品:商品-编号1
    消费者1 进入等待
    生产者2 生产商品:商品-编号2
    消费者2 获得商品:商品-编号2
    消费者2 进入等待
    生产者2 生产商品:商品-编号3
    消费者3 获得商品:商品-编号3
    消费者3 进入等待
    生产者1 生产商品:商品-编号4
    消费者1 获得商品:商品-编号4
    消费者1 进入等待
    生产者1 生产商品:商品-编号5
    消费者2 获得商品:商品-编号5
    消费者2 进入等待
    ...

    运行结果分析二(把notify改成notifyAll):

    每生产一件商品时调用notifyAll,都会把所有的消费者唤醒。

    消费者1 进入等待
    消费者3 进入等待
    消费者2 进入等待
    生产者2 生产商品:商品-编号1
    消费者3 进入等待
    消费者2 获得商品:商品-编号1
    消费者1 进入等待
    消费者2 进入等待
    生产者2 生产商品:商品-编号2
    消费者2 获得商品:商品-编号2
    消费者1 进入等待
    消费者3 进入等待
    消费者2 进入等待
    生产者2 生产商品:商品-编号3
    消费者2 获得商品:商品-编号3
    ...

    来源:http://www.taoweiji.cn/index.php/archives/112

  • 相关阅读:
    hdu 1301 prime算法
    hdu 4763 kmp算法
    linux上安装程序出现的问题汇总
    linux之下载工具wget
    python之os模块
    管道和xargs的区别
    linux下查找文件或目录(which,whereis,locate,find)
    blast+学习之search tools
    linux的文件,目录操作命令(mv,rm,cp)
    PHPCMS V9 简单的二次开发
  • 原文地址:https://www.cnblogs.com/taoweiji/p/5188514.html
Copyright © 2011-2022 走看看