Lock对象Condition接口实现等待/通知

关键字Synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待通知,ReentrantLock借助Condition对象可以实现同样的功能,而且一个lock对象可以创建多个condition对象,从而能够选择性condition对象进行等待/通知

condition对象实现等待通知的简单案例

public class ConditionLockDemo {
	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	public void csleep(){
		try{
			lock.lock();
			System.out.println(Thread.currentThread().getName()+"current time :"+System.currentTimeMillis());
			condition.await();
			System.out.println(Thread.currentThread().getName()+"唤醒后 current time :"+System.currentTimeMillis());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	public void signal(){
		try{
			lock.lock();
			condition.signal();
		}finally{
			lock.unlock();
		}
	}
}

启动两个线程,分别调用两个方法

public static void main(String[] args) throws InterruptedException {
	final ConditionLockDemo cl = new ConditionLockDemo();
	Thread a = new Thread(new Runnable() {
		@Override
		public void run() {
			cl.csleep();
		}
	}, "A");
	Thread b = new Thread(new Runnable() {
		@Override
		public void run() {
			cl.signal();
		}
	}, "B");
	a.start();
	Thread.sleep(1000);
	b.start();
}

输出:

Acurrent time :1525329885799
A唤醒后 current time :1525329886799

从这个简单案例:

*  condition 对象是lock对象进行创建的,而且一个lock对象可以创建多个condition对象

*  等待通知的实现,借助condition 对象的await()方法进入阻塞状态释放锁,signal方法唤醒waiting的线程

await()和signal方法的调用必须都要先在获取到锁之后(lock.lock())

condition部分方法描述
方法描述
await()

当前线程进入waiting状态,并且释放当前线程的锁,当前线程被唤醒,直到其他线程调用signal、signalAll或者interrupt方法

如果线程从await方法返回,表示已经获取到锁

awaitUninterruptibly()和上面方法一致,区别在于对于其他线程的中断方法不敏感
awaitUntil(Date deadline)当前线程进入等待状态直到被通知、中断或者到某个时间点,如果没有到时间点就被通知,方法返回true,否则到了指定时间,返回false
signal()获取到锁后,唤醒处于waiting状态的线程
signalAll()获取到锁后,唤醒所有处在waiting状态的线程

condition实现生产者消费者模型

3个线程轮流打印1,2,3 。。。

思想:

3个线程,创建3个condition对象

3个线程读取同一个共享变量的值,然后根据值,判断是否进入阻塞状态

,如果不是阻塞状态,修改这个值,并唤醒下一个线程,  A-B-C-A轮流唤醒

public class ThreeConditionDemo {
	private Lock lock = new ReentrantLock();
	private Condition condition1 = lock.newCondition();
	private Condition condition2 = lock.newCondition();
	private Condition condition3 = lock.newCondition();
	private volatile int count = 1;
	public void printA() {
		try{
			lock.lock();
			while(count!=1){
				condition1.await();
			}
			Thread.sleep(1000);
			System.out.println("1");
			count = 2 ;
			condition2.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	public void printB(){
		try{
			lock.lock();
			while(count!=2){
				condition2.await();
			}
			Thread.sleep(1000);
			System.out.println("2");
			count = 3;
			condition3.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	public void printC(){
		try{
			lock.lock();
			while(count!=3){
				condition3.await();
			}
			Thread.sleep(1000);
			System.out.println("3");
			count = 1;
			condition1.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
}

启动三个线程测试:

public static void main(String[] args) {
		final ThreeConditionDemo tcd = new ThreeConditionDemo();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					tcd.printA();
				}
			}
		});
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					tcd.printB();
				}
			}
		});
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					tcd.printC();
				}
			}
		});
		t1.start();
		t2.start();
		t3.start();
	}
Object监视器锁和Condition方法的对比

对比项Object监视器方法Condition
前置条件获取object对象的锁调用lock.lock()获取锁
调用方法object.wait/notify,notifyAll

Condition condition = lock.newCondition()

condition.await/signal,signalAll

释放锁进入等待状态,能够不响应中断不支持支持
释放锁进入超时等待支持支持
等待队列的个数1个

多个,lock可以创建多个condition,调用一个condition.await方法

就加入等待队列中


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值