线程间通信(生产者-消费者模式)

作者: wilsoncai 分类: 多线程 发布时间: 2018-01-06 00:39

有如下情形线程A向盘子里放桔子(盘子很小只能容得下个桔子)放完桔子后如果其它线程没有来拿桔子则A下次
再放桔子时留在盘子里上次那个桔子就被覆盖掉了(现实并非这样)但我们并不希望这个可口桔子就这样被第 2个
桔子覆盖掉我们理想情况是:线程A每次在盘子里放完个桔子后马上通知其它线程来取这个桔子这时线程A就暂停
放桔子在盘子里其它线程取走桔子的后马上通知A桔子已经被取走这时A继续放下个桔子并通知其它线程来取这
样反复下去(为了不让产生者永久放消费者永久地取可限定生产者共要放100次桔子)……于是放个就取走个所有
桔子都被成功取走
在上述案例子中线程A和线程B的间是生产者和消费者关系线程A生产桔子把桔子在盘子里线程B从盘子里拿走桔
子享受美味而且为了达到生产个拿走个这样对过程线程A必须告诉线程B:桔子已经放好了来拿吧你拿走了我再放
下个当线程B拿走后必须告诉线程A:我把桔子拿走了你快放下个吧线程A和B互相告诉对方动作就是线程间通信
取放桔子整个过程涉及到了 4个对象分别是生产者(线程A)消费者(线程B)消费商品(桔子)商店(盘子)因此可以把
上述过程看作是生产者和消费者在商店里交易桔子下图描绘了上述整个过程

public class ProConTest {
	public static void main(String[] args) {
		Panel pan = new Panel();
		Consumer c = new Consumer(pan);
		Producer p = new Producer(pan, c);
		c.setDaemon(true);/*将消费者设为守护线程也就是说当生产者不再生产时消费者立即主动不再消费*/
		p.start();
		c.start();
	}
}

public class Consumer extends Thread{
	Panel pan;

	public Consumer(Panel pan) {
		this.pan = pan;
	}

	public void run(){
		synchronized(this){
			while(true){
			if(pan.isBlank){
			try{
				wait();
			}
			catch(Exception ex){
				ex.printStackTrace();}
			}
			pan.getOrange();
			notify();
			}
		}
	}
}
public class Producer extends Thread {
	Panel pan = null;
	Consumer c = null;

	public Producer(Panel pan, Consumer c) {
		this.pan = pan;
		this.c = c;
	}

	public void run() {
		synchronized (c) {
			int count = 0;
			// 生产者共要生产100个桔子
			while (count < 100) {
				if (!pan.isBlank) {
					try {
						c.wait();
					} catch (Exception ex) {
						ex.printStackTrace();
					}
					count++;
				}
				double orgWeight = Math.random() * 100;
				Orange org = new Orange(orgWeight, "red");
				pan.putOrange(org);
				c.notify();
			}
		}
	}
}
public class Panel {
	public boolean isBlank = true;
	private Orange org;

	public void putOrange(Orange org) {
		this.org = org;
		isBlank = false;
		System.out.println("I put: " + org.toString());
	}

	public Orange getOrange(){
		System.out.println("I get: " + org.toString());
		isBlank = true;
		return org;
	}
}
public class Orange {
	double weight;
	String color;
	public Orange(double weight, String color){
	this.weight = weight;
	this.color = color;
	}
	public String toString() {
		return "Orange, weight = " + weight + ", color = " + color;
	}
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注