为了让线程与线程之间进行通信,Java包含了通过wait(),notify()和nottifyAll()等方法来实现一个进程间通信机制。这些方法在对象中是用final方法实现的,所以所有的类都可以含有它们。这三个方法仅在synchronized()方法中才能被调用
这些方法都是在Object类中被声明的:
- wait()告知被调用的线程放弃管程进入睡眠直到其他线程进入相同的管程并且调用notify()。
- notify()恢复相同对象中第一个调用wait()的线程。
- notifyAll()恢复相同对象中所有调用wait()的线程。具有最高优先级的线程最先运行。
public class Test {
public static void main(String[] args) {
Food food=new Food();
Consumer c=new Consumer(food);
Producer p=new Producer(food);
}
}
class Food {
private boolean FLAG = false;
private int i=0;
//生产食物
public synchronized void put(int i) throws InterruptedException{
if(FLAG)
wait();
System.out.println("put :"+i);
this.i=i;
FLAG=true;
notify();
}
//消费食物
public synchronized void get() throws InterruptedException{
if(!FLAG)
wait();
System.out.println("get :"+this.i);
FLAG=false;
notify();
}
}
class Producer implements Runnable {
private Food food=null;
private Thread th=null;
public Producer(Food food) {
th=new Thread(this);
this.food=food;
th.start();
}
@Override
public void run() {
int i=0;
try {
while(i<10){
food.put(++i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private Food food=null;
private Thread th=null;
public Consumer(Food food) {
th=new Thread(this);
this.food=food;
th.start();
}
@Override
public void run() {
int i=0;
try {
while(i<10){
food.get();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
同时启动两个线程,一个消费者,一个生产者,当生产者生产食物时,消费者进入wait()等待,然后生产者生产好食物,调用notify()方法通知消费者,这时候消费者从get()方法中wait中苏醒,消费了食物,进而又调用notify()方法来通知生产者继续生产食物。
下面是程序运行结果:
put :1
get :1
put :2
get :2
put :3
get :3
put :4
get :4
put :5
get :5
put :6
get :6
put :7
get :7
put :8
get :8
put :9
get :9
put :10
get :10
可以看出每次都是先put一个,然后再get一个,显示了两个线程的同步行为。