スレッド間通信(生産者-消費者モード)


参照
次のようなケースがあります.スレッドAは皿にみかんを入れます.(皿が小さくて次のみかんしか入れられません).みかんを入れた後、他のスレッドがみかんを取りに来なかったら、Aは次のようにします.
みかんを置くときは皿に残しておく前回はそのみかんが覆われていました(現実はそうではありません)しかし、私たちはこのおいしいみかんがこのように2番目に覆われることを望んでいません.
オレンジが私たちを覆う理想的な状況は、スレッドAが皿にオレンジを入れた後、すぐに他のスレッドにこのオレンジを取りに来るように通知するたびにスレッドAが一時停止することです.
みかんを皿に入れて他のスレッドでみかんを取った後、すぐにAみかんが取られたことを知らせます.このときAはみかんを置いて他のスレッドに知らせて取りに来ます.
このように缲り返していくと(生产者が永久に消费者を放さないように生产者限定で生产者100回のミカンを放す)……そこで放すとすべてを取る
みかんはみな取りに成功した
上記のケースではスレッドAとスレッドBの間に生産者と消費者の関係スレッドAがオレンジを生産して皿にオレンジを入れるスレッドBが皿からオレンジを取り出す
おいしいものを食べて、生産に達するために持って行ってください.このようにプロセススレッドAはスレッドBに伝えなければなりません.オレンジはもう置いてあります.持ってきてください.持って行ってから入れます.
次はスレッドBが持って行ったらスレッドAに伝えなければなりません.みかんを持って行ったから、置いてください.スレッドAとBはお互いに動作がスレッド間通信であることを伝えます.
みかんを取り出すプロセスは、生産者(スレッドA)消費者(スレッドB)消費商品(オレンジ)ショップ(皿)の4つの対象に及ぶため、
上記のプロセスは、生産者と消費者が店でオレンジを取引していると見なされています.次の図は、上記のプロセス全体を示しています.
Code:
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;
	}
}