Thinking in Java学习笔记 吐司的制作和消费过程

本文介绍了一个使用Java并发包中的LinkedBlockingQueue实现的土司生产线程模型。生产线由Toaster(烤面包机)、Butterer(涂抹黄油)、Jammer(涂抹果酱)和Eater(吃面包的人)四个环节组成,每个环节通过队列传递任务。

多个LinkedBlockingQueue队列,每个流程都有一个或两个队列,从上一个流程的队列中获取吐司,本流程处理完毕之后放入下一流程的队列

每个流程通过LinkedBlockingQueue.take()方法取队列中的任务时,如果上一个流程没有完成任务,队列是空的,则会堵塞在take()方法这里

源码如下:

public E take() throws InterruptedException {
        E x;
        int c = -1;
        final AtomicInteger count = this.count;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lockInterruptibly();
        try {
                while (count.get() == 0) {
                    notEmpty.await();
                }
            x = dequeue();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }



TostOMatic.java


package com.test.concurrent;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/*
 * 
 * 土司生产者与消费者
 * 生产者包括toast、butter和jam三个流程
 */
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;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		try {
			while(!Thread.interrupted()){
				TimeUnit.MILLISECONDS.sleep(100+rand.nextInt(500));
				Toast t=new Toast(count++);
				System.out.print(t+"  ");
				toastQueue.put(t);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("Toaster InterruptedException");
			e.printStackTrace();
		}
		
		System.out.println("-----------Toaset off----------------------");
	}
	
}

class Butterer implements Runnable{
	private ToastQueue dryQueue, butteredQueue;
	public Butterer(ToastQueue dry, ToastQueue buttered){
		dryQueue=dry;
		butteredQueue=buttered;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		try {
			while(!Thread.interrupted()){
				Toast t=dryQueue.take();
				t.butter();
				System.out.print(t+"  ");
				butteredQueue.put(t);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("butterer InterruptedException");
			e.printStackTrace();
		}
		
		System.out.println("----------butter off------------------------------");
	}
	
}
class Jammer implements Runnable{
	private ToastQueue butteredQueue,finishedQueue;
	public Jammer(ToastQueue buttered,ToastQueue finished){
		butteredQueue=buttered;
		finishedQueue=finished;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		try {
			while(!Thread.interrupted()){
				Toast t=butteredQueue.take();
				t.jam();
				System.out.print(t+"   ");
				finishedQueue.put(t);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("Jammer InterruptedException");
			e.printStackTrace();
		}
		
		System.out.println("------------jam off---------------------");
	}
	
}
class Eater implements Runnable{
	private ToastQueue finishedQueue;
	private int counter=0;
	public Eater(ToastQueue finished){
		finishedQueue=finished;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			while(!Thread.interrupted()){
				Toast t=finishedQueue.take();
				if(t.getId()!=counter++||t.getStatus()!=Toast.Status.JAMMED){
					System.out.println(">>>>>>Error:"+t);
				}else{
					System.out.println("   Chomp!! "+t);
				}
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("Eater InterruptedException");
			e.printStackTrace();
		}
		System.out.println("-----------------Eater off-----------------");
	}
	
}
public class TostOMatic {
	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));
		exec.execute(new Eater(finishedQueue));
		
		TimeUnit.SECONDS.sleep(5);
		exec.shutdownNow();
		
	}
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值