1. wait 和 notify
wait() 方法是Object类中的方法,他的作用是让当前线程进入等待状态,而使用notify() 方法可以唤醒。
- wait(long): void ,参数是毫秒,表示等待毫秒数,直到时间结束或被唤醒;
- wait(long, int): void ,第一个参数是毫秒,第二个参数是纳秒,如果纳秒在0-999999之间,则第一个参数值+1, 最后调用wait(long) 方法;
- wait(): void ,调用wait(0) ,表示无限等待。
- notify(): void,随机唤醒一个正在等待中的线程
- notifyAll():void ,唤醒所有正在等待中的线程
调用上述方法前,得保证当前线程是此对象的监视器所有者,即要获得对象的锁,否则直接调上述方法,会报出 java.lang.IllegalMonitorStateException 的错误。
简单的例子1:
public class Test1 {private static final Logger log = LoggerFactory.getLogger(Test1.class);// 自定义锁private final static Object obj = new Object();public static void main(String[] args) throws InterruptedException {Thread thread = new Thread("thread1") {@Overridepublic void run() {try {synchronized (obj){log.debug("wait()");obj.wait();}} catch (InterruptedException e) {e.printStackTrace();}log.debug("唤醒后的操作");}};thread.start();Thread.sleep(1000);synchronized (obj){obj.notify();log.debug("唤醒");}}
}
运行结果:
2021-04-25 22:31:49.151 [thread1] - wait()
2021-04-25 22:31:50.152 [main] - 唤醒
2021-04-25 22:31:50.152 [thread1] - 唤醒后的操作
2. wait 和 sleep
wait 和 sleep 都是可以让线程进入休眠的状态,但是具体的又有很大的不同。
sleep | wait | |
---|---|---|
所属类 | Thread 类中的静态方法 | Object 类中的非静态方法 |
参数 | 有参 | 有参和无参 |
调用后的线程状态 | TIMED_WAITING | WAITING(无参时) 或 TIMED_WAITING |
锁 | 不会释放锁 | 会释放锁 |
使用场景 | 任何地方都能使用 | 需取得锁后,才能调用 |
例子:
根据运行结果的时间来判断会不会释放锁。
测试sleep不会释放锁:
public class Test1 {private static final Logger log = LoggerFactory.getLogger(Test1.class);// 自定义锁private final static Object obj = new Object();public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread("thread1") {@Overridepublic void run() {try {synchronized (obj){log.debug("sleep(5000) 中...");Thread.sleep(5000);}log.debug("休眠结束...");} catch (InterruptedException e) {e.printStackTrace();}}};thread1.start();Thread.sleep(1000);log.debug("线程1:{}",thread1.getState());synchronized (obj){log.debug("正在访问obj...");}}
}
运行结果:
2021-04-25 22:55:50.762 [thread1] - sleep(5000) 中...
2021-04-25 22:55:51.762 [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:55.764 [thread1] - 休眠结束...
2021-04-25 22:55:55.764 [main] - 正在访问obj...
测试wait会释放锁:
public class Test1 {private static final Logger log = LoggerFactory.getLogger(Test1.class);// 自定义锁private final static Object obj = new Object();public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread("thread1") {@Overridepublic void run() {try {synchronized (obj){log.debug("wait(5000) 中...");obj.wait(5000);}log.debug("休眠结束...");} catch (InterruptedException e) {e.printStackTrace();}}};thread1.start();Thread.sleep(1000);log.debug("线程1:{}",thread1.getState());synchronized (obj){log.debug("正在访问obj...");}}
}
运行结果
2021-04-25 22:55:07.307 [thread1] - wait(5000) 中...
2021-04-25 22:55:08.308 [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:08.308 [main] - 正在访问obj...
2021-04-25 22:55:12.308 [thread1] - 休眠结束...