一、特点
wait()和notify()方法并不是线程对象的方法,是Java中任何一个Java对象都有的方法,并不特殊。
二、wait()方法的作用
Object obj = ``new Object();
obj.wait();
表示:obj.wait();方法的调用,会让“当前线程(正在obj对象上活动的线程)”进入等待状态。
三、notify()方法的作用
Object obj = ``new Object();
obj.notify();
表示:唤醒正在obj对象上等待的线程。
补充:
Object obj = ``new Object();
obj.notifyAll();
四、wait()和notify()的使用
【notify】随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态。该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常.
【wait】导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
总结:wait()和notify()方法都是建立在[synchronized]线程同步的基础之上
demo实例:
主方法:
public class TestDay2 {
public static void main(String[] args) {
//1、创建一个仓库对象,共享的
List list = new ArrayList();
//生产者线程
Thread t1 = new Thread(new Producer(list));
//消费者线程
Thread t2 = new Thread(new Consumer(list));
t1.setName("生产者生产:");
t2.setName("消费者消费:");
t1.start();
t2.start();
}
}
生产者:
public class Producer implements Runnable {
private List list;
public Producer(List list){
this.list = list;
}
@Override
public void run() {
// 一直生产
while (true) {
// 给仓库对象list加锁
synchronized (list) {
if (list.size() > 0) { //大于0,说明仓库list中已有一个元素
try {
//当前线程进入等待状态,并且释放Producer之前占有的list集合的锁
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//程序能够执行到这里说明仓库是空的,可以生产
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "----->" + obj);
//唤醒消费者消费
list.notifyAll();
}
}
}
}
消费者:
public class Consumer implements Runnable{
private List list;
public Consumer(List list){
this.list = list;
}
@Override
public void run() {
//一直消费
while (true){
synchronized (list){
if (list.size()==0){
//仓库已经空了,消费者线程等待
//释放掉list集合 的锁
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//程序能够实现到这里,说明仓库中已有数据,可以消费了
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName()+"---->"+obj);
//唤醒生产者生产
list.notifyAll();
}
}
}
}