目录
1.wait()方法
2.notify()方法
3.notifyAll()方法
4.wait()和sleep()方法的区别
由于线程之间是抢占式执行的,因此线程之间执行的先后顺序难以预知。但是在实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序。
完成这个协调工作,主要涉及三个方法。
wait()/wait(long timeout):让当前线程进入等待状态
notify()/notifyAll():唤醒在当前对象上等待的线程
wait()方法,notify()方法和notifyAll()方法都是Object类的方法。
1.wait()方法
wait():让线程等待一段时间,没有时间限制
wait(long):让线程等待一段时间,有时间限制的等待,指定的时间到了就不等了
wait做的事情:
- 使当前执行代码的线程进行等待(把线程放到等待队列中)
- 释放当前的锁
- 满足一定条件时被唤醒,重新尝试获取这个锁
wait要搭配synchronized来使用,脱离synchronized使用wait会直接抛出异常。
wait结束等待的条件:
- 其它线程调用该对象的notify方法
- wait等待时间超市
- 其它线程调用该等待线程的interrupted方法,导致wait抛出interruptedException异常
join()和wait()方法的区别:
join()方法的作用也是让线程去等待。二者的不同之处在于:
- join()是让调用方去等,wait()是让执行方去等
- join()是Thread类中定义的方法,wait和notify是Object类中定义的方法
用一个场景来演示一下join,wait,notify的功能:
2.notify()方法
notify():唤醒等待中的一个线程,直接参与锁竞争
如果有多个线程等待,则由线程调度器随机挑选出一个呈wait状态的线程(不存在”先来后到“)
在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是同步代码块之后才会释放对象锁。
示例代码:
package com.bitejiuyeke.lesson04;
/**
* @Author 比特就业课
* @Date 2023-05-05
*/
public class Demo31_Wait_Notify {
private static Object locker = new Object();
public static void main(String[] args) {
// 买包子线程
Thread t1 = new Thread(() -> {
while (true) {
System.out.println(Thread.currentThread().getName() + " wait 之前");
try {
// 等待资源,线程会被阻塞
synchronized (locker) {
locker.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " wait 之后");
System.out.println("=============================");
}
}, "t1");
// 启动线程
t1.start();
// 包子铺老板线程
Thread t2 = new Thread(() -> {
while (true) {
System.out.println(Thread.currentThread().getName() + " notify 之前");
// 唤醒时也使用同一个锁对象
synchronized (locker) {
locker.notify();
}
System.out.println(Thread.currentThread().getName() + " notify 之后");
// 等待一会
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2");
// 启动线程
t2.start();
}
}
3.notifyAll()方法
notifyAll():唤醒等待中的全部线程,线程共同去参与锁竞争
4.wait()和sleep()方法的区别
1.本质上来说都是让线程阻塞等待,但是两个方法没有什么关系
2.wait是Object类中定义的方法,sleep是Thread类中定义的方法
3.wait必须和synchronized搭配使用,调用之后会释放锁,sleep只是让线程进入休眠和锁没有关系