zoukankan      html  css  js  c++  java
  • java 中的阻塞队列

    1、什么是阻塞队列:

    • 支持阻塞的插入方法,意思是当队列满时,队列会阻塞插入元素的线程,知道队列不满。
    • 支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空。

      插入和移除操作的4种处理方式:

    方法/处理方式  抛出异常  返回特殊值  一直阻塞  超时退出
    插入方法 add(e) offer(e) put(e) offer(e, time, unit)
    移除方法 remove() poll() take()  poll(time, unit)
    检查方法 element() peek()  不可用  不可用

    2、java里的阻塞队列: 

    1. ArrayBlockingQueue:是一个用数组实现的有界阻塞队列。
    2. LinkedBlockingQueue:是一个永链表实现的有界阻塞队列。
    3. PriorityBlockingQueue:是一个支持优先级的无界阻塞队列。
    4. DealyQueue:是一个支持延时获取元素的无界阻塞队列。
    5. SynchronousQueue:是一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,否则不能继续添加元素。
    6. LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列。
    7. LinkedTransferQueue:是一个由链表结构组成的无界阻塞TransferQueue队列。

        重点:

        DelayQueue非常有用,可以将DelayQueue运用在以下应用场景。

      • 缓存系统的设计,可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能获取元素,标识缓存有效期到了。
      • 定时任务调度,使用DelayQueue保存当天将会执行的任务和执行时间。一旦从DelayQueue中获取到任务就开始执行,比如TimerQueue就是使用此实现的。

    3、阻塞队列的实现原理:
      使用通知模式实现。所谓通知模式,就是当生产者往满的队列里添加元素时会阻塞住生产者,当消费者消费了一个队列中的元素后,会通知生产者当前队列可用。查看ArrayBlockingQueue源码发现使用了Condition来实现,代码如下.

        private final Condition notEmpty;
        private final Condition notFull;
    
        public ArrayBlockingQueue(int capacity, boolean fair) {
            if (capacity <= 0)
                throw new IllegalArgumentException();
            this.items = new Object[capacity];
            lock = new ReentrantLock(fair);
            notEmpty = lock.newCondition();
            notFull =  lock.newCondition();
        }
    
        public void put(E e) throws InterruptedException {
            checkNotNull(e);
            final ReentrantLock lock = this.lock;
            lock.lockInterruptibly();
            try {
                while (count == items.length)
                    notFull.await();
                enqueue(e);
            } finally {
                lock.unlock();
            }
        }
    
        public E take() throws InterruptedException {
            final ReentrantLock lock = this.lock;
            lock.lockInterruptibly();
            try {
                while (count == 0)
                    notEmpty.await();
                return dequeue();
            } finally {
                lock.unlock();
            }
        }
        private void enqueue(E x) {
            // assert lock.getHoldCount() == 1;
            // assert items[putIndex] == null;
            final Object[] items = this.items;
            items[putIndex] = x;
            if (++putIndex == items.length)
                putIndex = 0;
            count++;
            notEmpty.signal();
        }
  • 相关阅读:
    hdu 4686 Arc of Dream
    监测系统的情况,你必须知道的两三事!
    [置顶] access函数-linux
    IE9 "CSS 因 Mime 类型不匹配而被忽略“问题
    [置顶] mkdir函数-linux
    adb 异常报错----adb server is out of date. killing... ADB server didn't ACK * failed to start daemon *
    Hbase深入学习(一) 什么是hbase
    Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)
    组队练习赛(Regionals 2012, North America
    CSS 注意事项
  • 原文地址:https://www.cnblogs.com/gouge/p/9122123.html
Copyright © 2011-2022 走看看