1、Object的wait()
Object类:
1)源码:
public final void wait() throws InterruptedException {
wait(0);
}
2)解释:
- Object的wait方法,是当前线程调用synchronized后获取到了对象的锁之后才可以使用
- 调用wait()让当前线程进入一个waitSet(可以理解为有一个休息室),这样其他等待同一个对象锁的线程有机会获得锁
- 唤醒对象上等待的线程需要配合notify()或者notifyAll()方法使用
3)使用示例:
public class TestWaitNotify {
final static Object obj = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
},"t1").start();
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
},"t2").start();
// 主线程两秒后执行
sleep(0.5);
log.debug("唤醒 obj 上其它线程");
synchronized (obj) {
// obj.notify(); // 唤醒obj上一个线程
obj.notifyAll(); // 唤醒obj上所有等待线程
}
}
}
2、Condition的await()
Condition类:
1)源码
void await() throws InterruptedException;
2)解释:
- Condition类上的wait方法,配合ReentrantLock (可重入锁)使用
- 调用await()让当前线程进入一个waitSet(可以理解为有一个休息室),这样其他等待同一个对象锁的线程有机会获得锁,这点和object.wait()一致
- 唤醒对象上等待的线程需要配合signal()或者signalAll()方法使用
- Condition 相当于lock对象的特定的休息室,可以创建不同的condition,来分别进行等待
3)使用示例:
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
//创建一个新的条件变量(休息室)
Condition condition = lock.newCondition();
lock.lock();
//进入休息室等待
condition.await();
//condition.signal(); //唤醒当前休息室的某个线程
condition.signalAll(); //唤醒当前休息室的所有线程
lock.unlock();
}