TIJ -- 吐司BlockingQueue

  1. 吐司BlockingQueuejava

    考慮下面這個使用BlockingQueue的示例。有一臺機器具備三個任務:一個製做吐司,一個給吐司抹黃油,另外一個在抹過黃油的吐司上吐果醬。咱們能夠經過各個處理過程之間的BlockingQueue來運行這個吐司製做程序:dom

  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 : this

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通訊。spa

  5.  鳴謝.net

    LinkedBlockingQueue源碼分析(JDK8)設計

    LinkedBlockingQueue源碼分析code

  6. 啦啦啦對象

相關文章
相關標籤/搜索