阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用Condition

26次阅读
没有评论

共计 1133 个字符,预计需要花费 3 分钟才能阅读完成。

使用 ReentrantLock 比直接使用 synchronized 更安全,可以替代 synchronized 进行线程同步。

但是,synchronized可以配合 waitnotify实现线程在条件不满足时等待,条件满足时唤醒,用 ReentrantLock 我们怎么编写 waitnotify的功能呢?

答案是使用 Condition 对象来实现 waitnotify的功能。

我们仍然以 TaskQueue 为例,把前面用 synchronized 实现的功能通过 ReentrantLockCondition来实现:

class TaskQueue {private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private Queue<String> queue = new LinkedList<>();

    public void addTask(String s) {lock.lock();
        try {queue.add(s);
            condition.signalAll();} finally {lock.unlock();
        }
    }

    public String getTask() {lock.lock();
        try {while (queue.isEmpty()) {condition.await();
            }
            return queue.remove();} finally {lock.unlock();
        }
    }
}

可见,使用 Condition 时,引用的 Condition 对象必须从 Lock 实例的 newCondition() 返回,这样才能获得一个绑定了 Lock 实例的 Condition 实例。

Condition提供的 await()signal()signalAll() 原理和 synchronized 锁对象的 wait()notify()notifyAll() 是一致的,并且其行为也是一样的:

  • await()会释放当前锁,进入等待状态;
  • signal()会唤醒某个等待线程;
  • signalAll()会唤醒所有等待线程;
  • 唤醒线程从 await() 返回后需要重新获得锁。

此外,和 tryLock() 类似,await()可以在等待指定时间后,如果还没有被其他线程通过 signal()signalAll()唤醒,可以自己醒来:

if (condition.await(1, TimeUnit.SECOND)) {// 被其他线程唤醒
} else {// 指定时间内没有被其他线程唤醒
}

可见,使用 Condition 配合Lock,我们可以实现更灵活的线程同步。

小结

Condition可以替代 waitnotify

Condition对象必须从 Lock 对象获取。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计1133字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中