最近在看进程通信这块,觉得用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();
}
}
}
}
一、这上面有两个类:
1、PrintQueue
该类是打印队列类,用来添加打印字符串和打印字符串(实际是移除)。其中add方法和remove方法都是被synchronized修饰的:即对于同一个PrintQueue对象,add和remove方法是受同步保护的。
2、Printer
该类用来运行PrintQueue对象的remove方法的。
二、执行的结果(每次执行结果顺序可能会不一样)
already add str number : 0 and notify to remove
already add str number : 1 and notify to remove
Thread-1try to remove : number : 0
already add str number : 2 and notify to remove
Thread-0try to remove : number : 1
already add str number : 3 and notify to remove
already add str number : 4 and notify to remove
Thread-1try to remove : number : 2
already add str number : 5 and notify to remove
Thread-0try to remove : number : 3
already add str number : 6 and notify to remove
Thread-1try to remove : number : 4
already add str number : 7 and notify to remove
Thread-0try to remove : number : 5
already add str number : 8 and notify to remove
Thread-1try to remove : number : 6
already add str number : 9 and notify to remove
Thread-1try to remove : number : 7
Thread-1try to remove : number : 9
Thread-0try to remove : number : 8
Thread-1 is waitting ...
Thread-0 is waitting ...
already add str number : 0 and notify to remove
already add str number : 1 and notify to remove
already add str number : 2 and notify to remove
already add str number : 3 and notify to remove
already add str number : 4 and notify to remove
already add str number : 5 and notify to remove
already add str number : 6 and notify to remove
already add str number : 7 and notify to remove
already add str number : 8 and notify to remove
already add str number : 9 and notify to remove
Thread-0try to remove : number : 0
Thread-1try to remove : number : 1
Thread-1try to remove : number : 3
Thread-1try to remove : number : 4
Thread-1try to remove : number : 5
Thread-1try to remove : number : 6
Thread-1try to remove : number : 7
Thread-1try to remove : number : 8
Thread-1try to remove : number : 9
Thread-1 is waitting ...
Thread-0try to remove : number : 2
Thread-0 is waitting ...
三、分析
1、从执行结果可以看出来并不是每次执行notifyAll,wait进程就会被唤醒。
2、线程执行wait后就进入静默状态,直到notifyAll或者notify被执行
3、被synchronized修饰的方法,是已该对象实例为锁的
四、疑问
1、为啥不是每次执行notifyAll之后,wait就被唤醒???
还请知道的大牛指点一二