概述
想必大家都使用过wait()和notify()这两个方法把,这两个方法主要用于多线程间的协同处理,即控制线程之间的等待、通知、切换及唤醒。而RenentrantLock也支持这样条件变量的能力,而且相对于synchronized 更加强大,能够支持多个条件变量。
ReentrantLock条件变量使用
ReentrantLock类API
Condition newCondition()
: 创建条件变量对象
Condition类API
void await()
: 当前线程从运行状态进入等待状态,同时释放锁,该方法可以被中断void awaitUninterruptibly()
:当前线程从运行状态进入等待状态,该方法不能够被中断void signal()
: 唤醒一个等待在 Condition 条件队列上的线程void signalAll()
: 唤醒阻塞在条件队列上的所有线程
@Test
public void testCondition() throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
//创建新的条件变量
Condition condition = lock.newCondition();
Thread thread0 = new Thread(() -> {
lock.lock();
try {
System.out.println("线程0获取锁");
// sleep不会释放锁
Thread.sleep(500);
//进入休息室等待
System.out.println("线程0释放锁,进入等待");
condition.await();
System.out.println("线程0被唤醒了");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
thread0.start();
//叫醒
Thread thread1 = new Thread(() -> {
lock.lock();
try {
System.out.println("线程1获取锁");
//唤醒
condition.signal();
System.out.println("线程1唤醒线程0");
} finally {
lock.unlock();
System.out.println("线程1释放锁");
}
});
thread1.start();
thread0.join();
thread1.join();
}
复制代码
运行结果:
- condition的wait和notify必须在lock范围内
- 实现条件变量的等待和唤醒,他们必须是同一个condition。
- 线程1执行conidtion.notify()后,并没有释放锁,需要等释放锁后