一、关于wait()和notify()方法的简单说明
- wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify方法(或者notfyAll()方法)时才能唤醒等待池中的线程进入等锁池,如果线程重新获得对象的锁就可以进入就绪状态。
- 由于wait()所等待的对象必须先锁住,因此,它只能用在同步化程序段或者同步化方法内(切记切记),否则,会抛出异常IllegalMonitorStateException.
二、用wait()和nofity()实现消费者与生产者机制
商户类
作为消费者和生产者进程的成员类
public class Shoper {
static int num = 0;
public int getNum(){
return num;
}
public void addNum(){
num += 1;
}
public void subNum(){
num -= 1;
}
}
消费者
通过实现Runnable接口建立Consumer进程类
public class Consumer implements Runnable{
Shoper shoper;
public Consumer(Shoper shoper){
this.shoper = shoper;
}
@Override
public void run() {
synchronized(shoper){//此处不可省略,否则运行时会有问题,详见简单说明第2点
while(true){
try {
if(shoper.getNum() == 0){
//当前商品数量为0时
//放弃当前进程对shoper对象的对象锁
//当前线程暂停执行并进入等待池等待被唤醒
shoper.wait();
}
System.out.println("消费者消费了一件商品");
shoper.subNum();
shoper.notify();//唤醒生产者进程进行生产
} catch(Exception e){
e.printStackTrace();
}
}
}
}
}
生产者
同样通过实现Runnable接口建立Productor类
public class Productor implements Runnable{
Shoper shoper;
public Productor(Shoper shoper){
this.shoper = shoper;
}
@Override
public void run() {
synchronized(shoper){//此处不可省略,否则运行时会有问题,详见简单说明第2点
while(true){
try {
if(shoper.getNum() != 0){
//当前商品数量不为0时
//放弃当前进程对shoper对象的对象锁
//当前线程暂停执行并进入等待池等待被唤醒
shoper.wait();
}
System.out.println("生产者生产了一件商品");
shoper.addNum();
shoper.notify();//唤醒消费者进程进行消费
} catch(Exception e){
e.printStackTrace();
}
}
}
}
}
测试类
public class ShoperTest {
public static void main(String[] args){
Shoper shoper= new Shoper();//新建商户
Thread productor = new Thread(new Productor(shoper));//创建生产者进程
Thread consumer = new Thread(new Consumer(shoper));//创建消费者进程
//启动进程
consumer.start();
productor.start();
}
}
结果如下: