前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ReentrantLock和Condition理解及应用

ReentrantLock和Condition理解及应用

作者头像
1025645
发布2018-12-06 15:41:25
1.1K0
发布2018-12-06 15:41:25
举报
文章被收录于专栏:Android开发小工Android开发小工

Condition:

Condition是一个多线程间协调通信的工具类,使得某个,或者某些线程一起等待某个条件(Condition),只有当该条件具备( signal 或者 signalAll方法被带调用)时 ,这些等待线程才会被唤醒,从而重新争夺锁。

ReentrantLock:

(重入锁)是jdk的concurrent包提供的一种独占锁的实现。它继承自Dong Lea的 AbstractQueuedSynchronizer(同步器),确切的说是ReentrantLock的一个内部类继承了AbstractQueuedSynchronizer,ReentrantLock只不过是代理了该类的一些方法,可能有人会问为什么要使用内部类在包装一层? 我想是安全的关系,因为AbstractQueuedSynchronizer中有很多方法,还实现了共享锁,Condition(稍候再细说)等功能,如果直接使ReentrantLock继承它,则很容易出现AbstractQueuedSynchronizer中的API被无用的情况。

对比wati,notify,notifyAll

java 1.5 出现的显式协作Condition接口的 await、signal、signalAll 也可以说是普通并发协作 wait、notify、notifyAll 的升级;普通并发协作 wait、notify、notifyAll 需要与synchronized配合使用,显式协作Condition 的 await、signal、signalAll 需要与显式锁Lock配合使用(Lock.newCondition()),调用await、signal、signalAll方法都必须在lock 保护之内。

和wait一样,await在进入等待队列后会释放锁和cpu,当被其他线程唤醒或者超时或中断后都需要重新获取锁,获取锁后才会从await方法中退出,await同样和wait一样存在等待返回不代表条件成立的问题,所以也需要主动循环条件判断;await提供了比wait更加强大的机制,譬如提供了可中断或者不可中断的await机制等;特别注意Condition也有wait、notify、notifyAll方法,因为其也是Object,所以在使用显式协作机制时千万不要和synchronized 情况下的协作机制混合使用,避免出现诡异问题。

用一个stackoverflow的一个实现BlockingQueue例子让大家印象深刻一点: 用wait,notify,notifyAll实现:

代码语言:javascript
复制
public class BlockingQueue<T> {
    private Queue<T> mQueue = new LinkedList<>();
    private int mCapacity;

    public BlockingQueue(int capacity) {
        this.mCapacity = capacity;
    }

    public synchronized void put(T element) throws InterruptedException{
        while (mQueue.size() == mCapacity){
            wait();
        }
        mQueue.add(element);
        notify();
    }

    public synchronized T take() throws InterruptedException{
        while (mQueue.isEmpty()){
            wait();
        }
        T item = mQueue.remove();
        notify();
        return item;
    }

}

用await,signal,signalAll实现:

代码语言:javascript
复制
public class BlockingQueue<T> {
    private Queue<T> mQueue = new LinkedList<>();
    private int mCapacity;
    private Lock mLock = new ReentrantLock();
    private Condition mNotFull = mLock.newCondition();
    private Condition mNotEmpty = mLock.newCondition();

    public BlockingQueue(int capacity) {
        this.mCapacity = capacity;
    }

    public synchronized void put(T element) throws InterruptedException{
        mLock.lockInterruptibly();
        try {
            while (mQueue.size() == mCapacity){
                mNotFull.await();
            }
            mQueue.add(element);
            mNotFull.signal();
        }finally {
            mLock.unlock();
        }
    }

    public synchronized T take() throws InterruptedException{
        mLock.lockInterruptibly();
        try {
            while (mQueue.size() == 0){
                mNotEmpty.await();
            }
            T item = mQueue.remove();
            mNotEmpty.signal();
            return item;
        }finally {
            mLock.unlock();
        }
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.10.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 对比wati,notify,notifyAll
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档