使用wait和notify的条件
wait() 与 notify/notifyAll 方法必须在同步代码块中使用,如果不是在同步方法或同步代码块中使用则会报异常
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.example.demo.controller.Test3Controller.main(Test3Controller.java:26)
大概意思是:违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。
wait() 与 notify/notifyAll() 区别:
当执行wait()时,线程会把持有的锁立即释放,线程处于block状态,调用对应的notify或者notifyAll方法,线程处于runnable状态,竞争到锁和cpu时间就重新执行
wait(100) 线程会把持有的锁立即释放,线程处于block状态,与wait()不同的是,当超过这个设置时间后,线程处于runnable状态,重新竞争锁和cpu时间来执行,当然也可以在线程block时,调用notify使其恢复到runnbale状态
当执行notify/notifyAll方法时,会唤醒处于block状态的线程,直到执行完同步块后再释放锁,所以notify或者notifyAll一般写在末尾
notify 是唤醒一个block线程,使其处于runnable状态,竞争获取到锁和CPU时间后继续执行
notify是唤醒所有的block线程,使他们处于runnable状态,这些线程竞争获取锁和CPU时间后再继续执行
案例:
package com.example.demo.controller;
public class Test3Controller extends Thread{
private static Object c=new Object();
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":线程启动");
synchronized (c) {
try {
System.out.println(Thread.currentThread().getName()+":线程等待");
c.wait();
System.out.println(Thread.currentThread().getName()+":线程被唤醒");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread s=new Test3Controller();
s.start();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"线程开始唤醒"+s.getName()+"线程");
synchronized (c) {
c.notify();
}
}
}