Condition是在Java1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。
它的更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition
一个Condition包含一个等待队列。一个Lock可以产生多个Condition,所以可以有多个等待队列。
在Object的监视器模型上,一个对象拥有一个同步队列和等待队列,而Lock(同步器)拥有一个同步队列和多个等待队列。
Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。
调用Condition的await()、signal()、signalAll()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用
- Conditon中的await()对应Object的wait();
- Condition中的signal()对应Object的notify();
- Condition中的signalAll()对应Object的notifyAll()。
void await() throws 造成当前线程在接到信号或被中断之前一直处于等待状态。
与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态:
- 其他某个线程调用此 Condition 的 signal()方法,并且碰巧将当前线程选为被唤醒的线程;或者
- 其他某个线程调用此
Condition
的 signalAll() 方法; - 或者 其他某个线程中断当前线程,且支持中断线程的挂起
- 或者 发生“虚假唤醒”
在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证它保持此锁。
void signal()
唤醒一个等待线程。
如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 await 返回之前,该线程必须重新获取锁。
void signalAll()
唤醒所有等待线程。
如果所有的线程都在等待此条件,则唤醒所有线程。在从 await 返回之前,每个线程都必须重新获取锁。
创建锁以及condition对象
private Lock lock = new ReentrantLock();
private Condition produceCondition = lock.newCondition();
private Condition consumeCondition = lock.newCondition();
运用condition时将wait()替换成await();notify()替换成signal();
public void produce(int i) {
lock.lock();
try{
if (this.falg) {
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i % 2 == 0) {
this.setName("馒头");//这两个语句不能分开
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.color="白色";
}else {
this.setName("玉米饼");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setColor("黄色");
}
System.out.println("生产者生产一个"+color+name);
//改变商品有无的状态
falg = true;
//通知消费
//notifyAll();//唤醒所有等待的线程
consumeCondition.signalAll();
}finally {
lock.unlock();
}
}
public void consume () {
lock.lock();
try{
if (!this.falg) {
try {
consumeCondition.await();//让出了cpu也让出了锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有商品就消费商品
System.out.println("消费者消费一个产品:" + this.getColor() + this.getName());
//改变商品的有无状态
this.falg = false;
//通知生产者生产
// this.notify();//随机唤醒一个处于等待的线程
produceCondition.signalAll();
}finally {
lock.unlock();
}
}