zoukankan      html  css  js  c++  java
  • TIJ -- 吐司BlockingQueue

      1. 吐司BlockingQueue

        考虑下面这个使用BlockingQueue的示例。有一台机器具有三个任务:一个制作吐司,一个给吐司抹黄油,另一个在抹过黄油的吐司上吐果酱。我们可以通过各个处理过程之间的BlockingQueue来运行这个吐司制作程序:

      2. class : 

    package lime.thinkingInJava._021._005._004;
    
    import com.sun.corba.se.impl.oa.toa.TOA;
    
    import java.util.Random;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @Author : Lime
     * @Description :
     * @Remark :
     */
    class Toast{
        public enum Status{DRY,BUTTERED,JAMMED}
        private Status status = Status.DRY;
        private final int id;
        public Toast(int idn){id = idn;}
        public void butter(){
            status = Status.BUTTERED;
        }
        public void jam(){
            status = Status.JAMMED;
        }
        public Status getStatus(){
            return status;
        }
        public int getId(){
            return id;
        }
        public String toString(){
            return "Toast " + id + " : " + status;
        }
    }
    class ToastQueue extends LinkedBlockingQueue<Toast>{}
    
    class Toaster implements Runnable{
        private ToastQueue toastQueue;
        private int count = 0;
        private Random rand = new Random(47);
        public Toaster(ToastQueue tq){
            toastQueue = tq;
        }
        public void run(){
            try{
                while (!Thread.interrupted()){
                    TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(100));
                    //Make toast
                    Toast t = new Toast(count++);
                    System.out.println(t);
                    //Insert into queue
                    toastQueue.put(t);
                }
            } catch (InterruptedException e) {
                System.out.println("Toaster interrupted");
            }
            System.out.println("Toaster off");
        }
    }
    //Apply butter to toast
    class Butterer implements Runnable{
        private ToastQueue dryQueue ,butteredQueue;
        public Butterer(ToastQueue dry , ToastQueue buttered){
            dryQueue = dry;
            butteredQueue = buttered;
        }
        public void run(){
            try{
                while (!Thread.interrupted()){
                    //Blocks until next piece of toast is available;
                    Toast t = dryQueue.take();
                    t.butter();
                    System.out.println(t);
                    butteredQueue.put(t);
                }
            } catch (InterruptedException e) {
                System.out.println("Butterer interrupted");
            }
            System.out.println("Butterer off");
        }
    }
    //Apply jam to buttered toast;
    class Jammer implements Runnable{
        private ToastQueue butteredQueue,finishedQueue;
        public Jammer(ToastQueue buttered,ToastQueue finished){
            butteredQueue = buttered;
            finishedQueue = finished;
        }
        public void run(){
            try{
                while (!Thread.interrupted()){
                    //Blocks until next piece of toast is available;
                    Toast t = butteredQueue.take();
                    t.jam();
                    System.out.println(t);
                    finishedQueue.put(t);
                }
            } catch (InterruptedException e) {
                System.out.println("Jammer interrupted");
            }
            System.out.println("Jammer off");
        }
    }
    //Consume the toast;
    class Eater implements Runnable{
        private ToastQueue finishedQueue;
        private int counter = 0;
        public Eater(ToastQueue finished){
            this.finishedQueue = finished;
        }
        public void run(){
            try{
                while (!Thread.interrupted()){
                    //Blocks until next piece of toast is available;
                    Toast t = finishedQueue.take();
                    //Verify that the toast is coming in order;
                    //and that all pieces are getting jammed;
                    if(t.getId() != counter++ || t.getStatus() != Toast.Status.JAMMED){
                        System.out.println(">>>> Error : " + t);
                        System.exit(1);
                    }else{
                        System.out.println("Chomp ! " + t);
                    }
                }
            } catch (InterruptedException e) {
                System.out.println("Eater interrupted");
            }
            System.out.println("Eater off");
        }
    }
    public class ToastOMatic {
        public static void main(String[] args) throws InterruptedException {
            ToastQueue dryQueue = new ToastQueue(),
                    butteredQueue = new ToastQueue(),
                    finishedQueue = new ToastQueue();
            ExecutorService exec = Executors.newCachedThreadPool();
            exec.execute(new Toaster(dryQueue));
            exec.execute(new Butterer(dryQueue,butteredQueue));
            exec.execute(new Jammer(butteredQueue,finishedQueue));
            TimeUnit.SECONDS.sleep(5);
            exec.shutdownNow();
        }
    }

      3. Console : 

    Toast 0 : DRY
    Toast 0 : BUTTERED
    Toast 0 : JAMMED
    Toast 1 : DRY
    Toast 1 : BUTTERED
    Toast 1 : JAMMED
    Toast 2 : DRY
    Toast 2 : BUTTERED
    Toast 2 : JAMMED
    Toast 3 : DRY
    Toast 3 : BUTTERED
    Toast 3 : JAMMED
    Toast 4 : DRY
    Toast 4 : BUTTERED
    Toast 4 : JAMMED
    Toast 5 : DRY
    Toast 5 : BUTTERED
    Toast 5 : JAMMED
    Toast 6 : DRY
    Toast 6 : BUTTERED
    Toast 6 : JAMMED
    Toast 7 : DRY
    Toast 7 : BUTTERED
    Toast 7 : JAMMED
    Toast 8 : DRY
    Toast 8 : BUTTERED
    Toast 8 : JAMMED
    Toast 9 : DRY
    Toast 9 : BUTTERED
    Toast 9 : JAMMED
    Toast 10 : DRY
    Toast 10 : BUTTERED
    Toast 10 : JAMMED
    Toast 11 : DRY
    Toast 11 : BUTTERED
    Toast 11 : JAMMED
    Toast 12 : DRY
    Toast 12 : BUTTERED
    Toast 12 : JAMMED
    Toast 13 : DRY
    Toast 13 : BUTTERED
    Toast 13 : JAMMED
    Toast 14 : DRY
    Toast 14 : BUTTERED
    Toast 14 : JAMMED
    Toast 15 : DRY
    Toast 15 : BUTTERED
    Toast 15 : JAMMED
    Toast 16 : DRY
    Toast 16 : BUTTERED
    Toast 16 : JAMMED
    Toast 17 : DRY
    Toast 17 : BUTTERED
    Toast 17 : JAMMED
    Toast 18 : DRY
    Toast 18 : BUTTERED
    Toast 18 : JAMMED
    Toast 19 : DRY
    Toast 19 : BUTTERED
    Toast 19 : JAMMED
    Toast 20 : DRY
    Toast 20 : BUTTERED
    Toast 20 : JAMMED
    Toast 21 : DRY
    Toast 21 : BUTTERED
    Toast 21 : JAMMED
    Toast 22 : DRY
    Toast 22 : BUTTERED
    Toast 22 : JAMMED
    Toast 23 : DRY
    Toast 23 : BUTTERED
    Toast 23 : JAMMED
    Toast 24 : DRY
    Toast 24 : BUTTERED
    Toast 24 : JAMMED
    Toast 25 : DRY
    Toast 25 : BUTTERED
    Toast 25 : JAMMED
    Toast 26 : DRY
    Toast 26 : BUTTERED
    Toast 26 : JAMMED
    Toast 27 : DRY
    Toast 27 : BUTTERED
    Toast 27 : JAMMED
    Toast 28 : DRY
    Toast 28 : BUTTERED
    Toast 28 : JAMMED
    Toast 29 : DRY
    Toast 29 : BUTTERED
    Toast 29 : JAMMED
    Toast 30 : DRY
    Toast 30 : BUTTERED
    Toast 30 : JAMMED
    Toast 31 : DRY
    Toast 31 : BUTTERED
    Toast 31 : JAMMED
    Toast 32 : DRY
    Toast 32 : BUTTERED
    Toast 32 : JAMMED
    Toast 33 : DRY
    Toast 33 : BUTTERED
    Toast 33 : JAMMED
    Jammer interrupted
    Jammer off
    Butterer interrupted
    Butterer off
    Toaster interrupted
    Toaster off

      4. Toast是一个使用enum值的优秀示例。注意,这个示例中没有任何显式的同步(即使用Lock对象或synchronized关键字的同步),因为同步由队列(其内部是同步的)和系统的设计隐式地管理了 ------ 每片Toast在任何时刻都只由一个任务在操作。因为队列的阻塞,使得处理过程将被自动地挂起和恢复。你可以看到由BlockingQueue产生的简化十分明显。在使用显示的wait()和notifyAll()时存在的类和类之间的耦合被消除了,因为每个类都只和它的BlockingQueue通信。

      5.  鸣谢

        LinkedBlockingQueue源码分析(JDK8)

        LinkedBlockingQueue源码分析

      6. 啦啦啦

  • 相关阅读:
    linux之sed用法
    vim 设置tab空格个数
    centos 7远程登陆win10
    linux find命令学习
    CENTOS 7 修改默认启动内核
    Centos7更改默认启动模式
    centos 7创建桌面快捷方式
    修改centos中文为英文显示
    正则的sub
    超时或错误重试
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/7897056.html
Copyright © 2011-2022 走看看