`
Supanccy2013
  • 浏览: 215065 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java多线程-Producer-consumer(生产者消费者模式)

阅读更多
   多线程中生产者消费者模式是非常重要的模式,如果之前的几个模式都通晓了,这个模式也就水到渠成了。废话少说,下面开始模拟.
模拟功能需要实现如下要求:
1,厨师(MakerThread)会做蛋糕(String)放在桌子(Table)上。
2,桌子太小,顶多可以放3个蛋糕。
3,桌上已经放满3个蛋糕,而厨师还要放上蛋糕的话,会等待到桌子上出现空间为止。
4,客人(EaterThread)会拿桌上的蛋糕吃。
5,桌上没有蛋糕时,客人又要拿蛋糕的话,会等待到蛋糕放到桌子上为止。

涉及的类有:

package ProduceConsumerPattern;
public class Table {
	private final String[] buffer;
	private int tail;//下一个put的地方
	private int head; //下一个take的地方
	private int count;//buffer内的蛋糕数
	public Table(int count){
		this.buffer = new String[count];//生成一个指定容量盛放蛋糕的容器
		this.head = 0;  //设置下一个放蛋糕的数组索引值
		this.tail = 0;  //设置下一个拿蛋糕的数组索引值
		this.count = 0; //设置容器内含有的蛋糕的数量
	}
	/*
	 * 放置蛋糕
	 */
	public synchronized void put(String cake)throws InterruptedException{
	  System.out.println(Thread.currentThread().getName() + "puts:" + cake);
	  while(count >= buffer.length){//如果容器上有大于等于3个蛋糕的话线程进入Table的线程等待区
		wait();
	  }
	  buffer[tail] = cake;//如果容器里没有满的话,把蛋糕放进容器里
	  tail = (tail+1) % buffer.length;
	  count++;//增加蛋糕的数量
	  notifyAll();
	}
	//获取蛋糕
	public synchronized String take() throws InterruptedException{
		while(count<=0){
			wait();
		}
		String cake = buffer[head];
		head = (head+1) % buffer.length;
		count--;
		notifyAll();
		System.out.println(Thread.currentThread().getName() + "takes:" + cake);
        return cake;
	}
}


package ProduceConsumerPattern;
import java.util.Random;
public class MakerThread extends Thread{
	private final Random random;
	private final Table table;
	private static int id = 0;//蛋糕的流水号(每个线程都一样)
	public MakerThread(String name,Table table,long seed){
		super(name);
		this.table = table;
		this.random = new Random(seed);
	}
	public void run(){
		try {
			while(true){
				Thread.sleep(random.nextInt(1000));
				String cake = "[Cake No."+ nextId() + "by " + getName();
				table.put(cake);
			}
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public static synchronized int nextId(){
		return id++;
	}
}

package ProduceConsumerPattern;
import java.util.Random;
public class EaterThread extends Thread{
	private final Random random;
	private final Table table;
	public EaterThread(String name,Table table, long seed){
		super(name);
		this.table = table;
		this.random = new Random(seed);
	}
	public void run(){
		try {
			while(true){
				String cake = table.take();
				Thread.sleep(random.nextInt(1000));
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

}


package ProduceConsumerPattern;
public class Main {
	public static void main(String[] args) {
		Table table = new Table(3);
		new MakerThread("MakerThread-1",table,31415).start();
		new MakerThread("MakerThread-2",table,92653).start();
		new MakerThread("MakerThread-3",table,58979).start();
		new EaterThread("EaterThread-1",table,32384).start();
		new EaterThread("MakerThread-2",table,62643).start();
		new EaterThread("EaterThread-3",table,38327).start();
	}
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics