JAva言語プロセス通信学習


最近プロセス通信を見ていて、wait、notify、notifiAllでプロセス通信をするのは面白いと思います.
私が書いた小さな例を貼ってみましょう
package com.tsing.test1;

import java.util.LinkedList;

public class PrintQueue {
	
	private LinkedList<String> queue = new LinkedList<String>();
	
	public synchronized void add(String str){
		queue.add(str);
		System.out.println("already add str "+str+" and notify to remove");
		notifyAll();
	}
	
	public synchronized String remove() throws InterruptedException{
		while(queue.size() == 0){
			System.out.println(Thread.currentThread().getName()+" is waitting ...");
			wait();
		}
		return queue.remove();
	}
	
	public static void main(String[] args){
		PrintQueue queue = new PrintQueue();
		
		Printer p = new Printer(queue);
		new Thread(p).start();
		new Thread(p).start();
		
		for(int i = 0 ; i < 10 ; i++){
			queue.add("number : "+i);
		}
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i = 0 ; i < 10 ; i++){
			queue.add("number : "+i);
		}
	}
}

 
package com.tsing.test1;
/**
 *  
 * @author Administrator
 *
 */
public class Printer implements Runnable{

	private PrintQueue queue;
	
	public Printer(PrintQueue queue){
		this.queue = queue;
	}
	
	public void run() {
		while(true){
			try {
				System.out.println(Thread.currentThread().getName() +"try to remove : "+queue.remove());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

 
一、この上に2つのクラスがあります.
1、PrintQueue
このクラスは、印刷文字列と印刷文字列を追加するための印刷キュークラスです(実際には削除されます).ここでaddメソッドとremoveメソッドはsynchronizedによって修飾されます.すなわち、addメソッドとremoveメソッドは同じPrintQueueオブジェクトに対して同期的に保護されます.
2、Printer
このクラスはPrintQueueオブジェクトのremoveメソッドを実行するために使用されます.
 
二、実行した結果(毎回実行結果の順序が異なる場合がある)
already add str number : 0 and notify to removealready add str number : 1 and notify to removeThread-1try to remove : number : 0already add str number : 2 and notify to removeThread-0try to remove : number : 1already add str number : 3 and notify to removealready add str number : 4 and notify to removeThread-1try to remove : number : 2already add str number : 5 and notify to removeThread-0try to remove : number : 3already add str number : 6 and notify to removeThread-1try to remove : number : 4already add str number : 7 and notify to removeThread-0try to remove : number : 5already add str number : 8 and notify to removeThread-1try to remove : number : 6already add str number : 9 and notify to removeThread-1try to remove : number : 7Thread-1try to remove : number : 9Thread-0try to remove : number : 8Thread-1 is waitting ...Thread-0 is waitting ...already add str number : 0 and notify to removealready add str number : 1 and notify to removealready add str number : 2 and notify to removealready add str number : 3 and notify to removealready add str number : 4 and notify to removealready add str number : 5 and notify to removealready add str number : 6 and notify to removealready add str number : 7 and notify to removealready add str number : 8 and notify to removealready add str number : 9 and notify to removeThread-0try to remove : number : 0Thread-1try to remove : number : 1Thread-1try to remove : number : 3Thread-1try to remove : number : 4Thread-1try to remove : number : 5Thread-1try to remove : number : 6Thread-1try to remove : number : 7Thread-1try to remove : number : 8Thread-1try to remove : number : 9Thread-1 is waitting ...Thread-0try to remove : number : 2Thread-0 is waitting ...
三、分析
1、実行結果からnotifyAllを実行するたびにwaitプロセスが起動するわけではないことがわかります.
2、スレッドがwaitを実行すると、notifyAllまたはnotifyが実行されるまでサイレント状態に入る
3、synchronizedによって修飾された方法は、オブジェクトインスタンスがロックされている
 
四、疑問
1、なぜnotifyAllを実行するたびにwaitが起動しないのですか??
まだ知っている大牛は一二を教えてください.