• 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列


    package cn.study.concurrency.ch14;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 使用condition作为挂起线程的信号
     * 这个是先进先出的队列
     * @author xiaof
     *
     * @param <T>
     */
    public class ConditionBoundedBuffer<T> {
        protected final Lock lock = new ReentrantLock();
        //数据队列长度
        private static final int BUFFER_SIZE = 1024;
        //建立两个condition,一个代表不为空,一个代表不满
        private final Condition notFull = lock.newCondition();
        private final Condition notEmpty = lock.newCondition();
        private final T[] items = (T[]) new Object[BUFFER_SIZE];
        private int tail, head, count;
        
        public void put(T x) throws InterruptedException
        {
            lock.lock();//这里在进行操作的时候上锁
            try {
                while(count == items.length)
                {
                    //如果是满的就挂起线程,等待变为notFull
                    notFull.await();
                }
                items[tail] = x;
                //判断是否是已经达到了满队列的情况
                if(++tail == items.length)
                    tail = 0;
                //计数值++
                ++count;
                //插入数据,队列肯定不是空的,那么进行非空信号发布
                notEmpty.signal();
            } finally{
                //执行完毕,切记一定要解锁
                lock.unlock();
            }
        }
        
        //获取数据,阻塞直到队列中有数据为止
        public T take() throws InterruptedException
        {
            lock.lock();//进行操作之前,先上锁
            
            try {
                while(count == 0)
                {
                    //如果队列中没有数据,那么就要进行现场挂起
                    notEmpty.await();
                }
                //得到数据,用来返回
                T t = items[head];
                items[head] = null;//吧输出出去的数据设为空
                if(++head == items.length)
                    head = 0; //重置队里索引
                --count;    //计数减一
                notFull.signal();//唤醒插入操作,因为获取出去一个数据,那么队列就一定有空位
                return t;
            } finally {
                //切记在执行完毕之后,不论成功与否,都要解锁
                lock.unlock();
            }
        }
        
    }
  • 相关阅读:
    JavaScript之DOM总结
    图书馆管理系统——模板建立
    JavaScript阶段总结(二)
    JavaScript阶段总结(一)
    机房重构反思之视图
    web服务代理
    若要在加载设计器前避免可能发生的数据丢失,必须纠正以下错误
    ”/”应用程序中的服务器错误
    无法显示您正在查找的页面,因为使用了无效的方法(http谓词)。
    hibernate树
  • 原文地址:https://www.cnblogs.com/cutter-point/p/6114179.html
Copyright © 2020-2023  润新知