Java提供了wait和notify,notifyall来实现等待唤醒的生产者和消费者模式,ReenTrantLock也同样提供了类似的机制,而且比前者更加灵活,前者调用notify唤醒的是虚拟机随即选择的等待线程。而ReenTrantLock的condition则可以有选择地唤醒。
值得注意的是,跟wait和notify一样的是,使用condition 的前提也是必须先进入锁,上例子:
java.lang.IllegalMonitorStateException --一般是没有获取到锁但是使用了需要先获得锁的接口调用
public class ReadeWriteLockTest implementsRunnable {
staticReentrantLock lock = new ReentrantLock();
staticCondition cond = lock.newCondition();
Stringtype;
/*@author : zhengrf1
* @date 创建时间:2017年3月9日 上午10:19:06
* @see java.lang.Runnable#run()
*/
@Override
publicvoid run() {
//TODO Auto-generated method stub
lock.lock();
System.out.println(Thread.currentThread().getName()+"获取到 锁,休息10秒");
try{
cond.await();
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println(Thread.currentThread().getName()+"释放锁");
}
/**
*
*@author : zhengrf1
* @throws InterruptedException
*@date 创建时间:2017年3月9日上午10:19:06
*/
publicstatic void main(String[] args) throws InterruptedException {
//TODO Auto-generated method stub
ReadeWriteLockTesttest = new ReadeWriteLockTest();
// ReadeWriteLockTestlock1 = new ReadeWriteLockTest();
// ReadeWriteLockTestlock2 = new ReadeWriteLockTest();
Threadtest1 = new Thread(test);
Threadtest2 = new Thread(test);
test1.start();
test2.start();
Thread.sleep(5000);
test.lock.lock();
test.cond.signalAll();
test.lock.unlock();
}
}
输出:
Thread-0获取到锁,休息10秒
Thread-1获取到锁,休息10秒
Thread-0释放锁
Thread-1释放锁
test.cond.signalAll();会唤醒所有因为调用test.cond.await而阻塞等待的线程
设置多个condition,唤醒等待某condition的所有线程
public class ReadeWriteLockTest implements Runnable{
staticReentrantLock lock = new ReentrantLock();
Conditioncond;
Stringtype;
ReadeWriteLockTest(Conditioncond){
this.cond=cond;
}
/*@author : zhengrf1
* @date 创建时间:2017年3月9日 上午10:19:06
* @see java.lang.Runnable#run()
*/
@Override
publicvoid run() {
//TODO Auto-generated method stub
lock.lock();
System.out.println(Thread.currentThread().getName()+"获取到 锁,休息10秒");
try{
cond.await();
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println(Thread.currentThread().getName()+"释放锁");
}
/**
*
*@author : zhengrf1
* @throws InterruptedException
*@date 创建时间:2017年3月9日上午10:19:06
*/
publicstatic void main(String[] args) throws InterruptedException {
//TODO Auto-generated method stub
Conditioncondtest = lock.newCondition();
Conditioncondtest2 = lock.newCondition();
ReadeWriteLockTestlock1 = new ReadeWriteLockTest(condtest);
ReadeWriteLockTestlock2 = new ReadeWriteLockTest(condtest2);
Threadtest1 = new Thread(lock1);
Threadtest2 = new Thread(lock2);
test1.start();
test2.start();
Thread.sleep(5000);
lock.lock();
condtest2.signalAll();
lock.unlock();
}
}
输出:
Thread-1获取到 锁,休息10秒
Thread-0获取到 锁,休息10秒
Thread-1释放锁
-- condtest2.signalAll();唤醒了condtest2对应的Thread-1,而condtest对应的Thread-0一直属于阻塞状态。