一、wait和notify的使用
- wait和notify的使用必须在synchronized锁定的代码块中,否则会报错
public class T1 {
static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
lock.notify();
}
}
原因可以解释为,这两个方法的使用都应该处于持有锁的场景
- wait方法是object类中的方法,wait方法在使用的过程中,需要在对应的锁对象上进行使用,以表明当前的线程放弃了锁持有的锁
synchronized (lock) {
System.out.println("ss");
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
- notify方法也是object里面的方法,这个方法调用的结果是随机唤醒一个因为调用了object.wait()方法进度waitset里面等待的线程,使得这个线程由waiting状态进入竞争锁的状态。而notifyAll方法是唤醒在waitset里面的所有线程,使得所有线程都可以去竞争锁
- notify随机唤醒以及notifyAll全部唤醒引起的虚假唤醒问题,原因是,某个线程调用wait方法本意是等待某个条件的产生,而唤醒后这个条件也没有产生,导致没有达到目的,因此这个线程尽管被唤醒,但是应该继续等待。解决的方法是加上一个while(true)循环条件
二、wait和sleep的区别
- wait是object类的方法,sleep是Thread类的方法。
- wait使用的过程中必须在synchronized修饰的代码块中,sleep不用
- wait不需要捕获异常,sleep必须捕获异常
- wait是释放锁的,sleep是不释放锁的