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

多个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();
		
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Thinking in Java》是一本经典的Java编程入门教材,通过阅读该书可以系统地学习Java编程的基础知识和高级概念。阅读过程中,我结合自己的学习体验和实践,进行了详细的学习笔记。 首先,该书从基础语法开始介绍,包括数据类型、控制语句、数组等。对于初学者来说,这些基础知识是最基本的,通过书中的示例代码和解析,我能够更好地理解这些概念和语法规则。 其次,书中对面向对象编程进行了深入的讲解。通过学习面向对象的思想,我明白了类、对象、继承、多态等概念的含义和使用方法。同时,书中还讲解了接口、内部类、异常处理等较为高级的概念,极大地拓宽了我的Java知识面。 另外,该书还介绍了Java的常见类库和工具,如字符串操作、集合框架、输入输出、线程等。这些内容对于实际开发非常有用,而且书中的示例代码也能帮助我更好地理解和应用这些类库和工具。 此外,该书通过大量的实例和案例,生动地展示了Java编程的实战应用。这些实例涵盖了各种不同的应用场景,从简单的程序到复杂的项目,都有所涉及。通过分析这些实例,我不仅可以学习到实际编程的技巧,还能提高自己的解决问题的能力。 总的来说,读完《Thinking in Java》后,我对Java编程有了更深入的理解和掌握。通过学习笔记的整理,我不仅复习了各个知识点,还加深了对这些概念的理解。希望这份学习笔记能够帮助到其他想要学习Java的同学,让他们能够更快地入门和掌握这门编程语言。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值