- wait notify不是线程对象专有的,所有对象都有
- 在synchronized基础上使用
- list.wait()作用:使当前线程无限等待,并释放锁
- list.notify():不释放锁
先上个例子:
生产Producer和消费Consumer,生产一个产品,消费一个产品。
用List做仓库,生产一个添加到list,消费一个list去掉一个。
原理:
list作为仓库有两个池,锁池和等待池。线程进入锁池抢锁,进入等待池等待被唤醒。
1.消费线程和生产线程同时执行,假设消费线程首先抢到锁,执行run()方法,此时仓库list没有产品,执行list.wait()并释放锁,消费线程从而进入等待池,生产线程抢到锁
2.生产线程抢到锁后执行run()方法,仓库list没有产品,从而生产一个o,存入仓库list,并执行list.notify(),告知等待池中的一个线程-只有消费线程,从而消费线程进入锁池等待抢锁。生产线程继续执行,因为仓库有产品,执行list.wait(),释放锁进入等待池,消费线程抢到锁。
3.消费线程执行run(),消费产品,并执行list.notify(),再执行list.wait(),进入等待池并释放锁。
然后就这样一直生产,一直消费,代码如下
import java.util.*;
public class Main {
public static void main(String[] args) {
List list=new ArrayList();//相当于仓库
Producer r1=new Producer(list);
Consumer r2=new Consumer(list);
Thread t1=new Thread(r1,"生产");
Thread t2=new Thread(r2,"消费");
t1.start();
t2.start();
try {
Thread.sleep(10);
r1.isTrue=false;
r2.isTrue=false;
} catch (InterruptedException e) {}
}
}
class Producer implements Runnable {
private List list;
public boolean isTrue=true;
public Producer(List list){
this.list=list;
}
@Override
public void run() {
while(isTrue){
synchronized(list){
if(list.size()<1){
Object o=new Object();
list.add(o);
System.out.println(Thread.currentThread().getName()+"--->"+"添加1个"+o);
list.notify();
}
try {
list.wait();
} catch (InterruptedException e) {}
}
}
}
}
class Consumer implements Runnable {
private List list;
public boolean isTrue=true;
public Consumer(List list){
this.list=list;
}
@Override
public void run() {
while(isTrue){
synchronized(list){
if(list.size()>0){
Object o=list.remove(0);
System.out.println(Thread.currentThread().getName()+"--->"+"减少1个"+o);
list.notify();
}
try {
list.wait();
} catch (InterruptedException e) {}
}
}
}
}