美文网首页
Day 35 BlockingQueue 实战及其原理

Day 35 BlockingQueue 实战及其原理

作者: 小周爱吃瓜 | 来源:发表于2022-04-22 23:56 被阅读0次
  • Queue 接口

优先级队列用二叉树排序.

分类

阻塞,是否有界

用的是ReentrantLock + Condition+CAS 来完成锁和线程阻塞唤醒机制

  1. ArrayBlockingQueue

  2. LinkedBlockingQueue

对比:


  • SynchronousQueue ,PriorityBlockingQueue 优先级队列 ,DelayQueue 延迟队列

用的都是Queue的结构

1. add() 添加数据 成功返回true,满了抛出异常 ---  注意会抛异常


public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

Screen Shot 2022-04-22 at 11.37.20 PM.png
  • 有可能出现取不到的场景,又不想干等着,所以可以设置超时时间.

offer(E e,long timeout,TimeUnit unit),超时则返回false.

总结

Screen Shot 2022-04-22 at 11.39.59 PM.png

所以很多都是用 poll,take, offer等

take不能刹车,一直等。 poll可以刹车,有阻塞时间.

LockSupport.parkNanos() 用的是LockSupport的api,可以指定park的时长.

Lock. lockInterruptibly() 

比对

ArrayBlockingQueue 有界
LinkedBlockingQueue,无界
PriorityBlockingQueue,优先级排序无界阻塞队列

Array: 初始就分配好了,额外空间开销小
Linked:  额外Node开销,长时间处理大批量数据时,GC压力大

   private final ReentrantLock takeLock = new ReentrantLock();


LinkedBlockingQueue:

2把锁,读锁和写锁,生产和消费并行执行,效率大大提升.

    /** Wait queue for waiting takes */
    private final Condition notEmpty = takeLock.newCondition();

    /** Lock held by put, offer, etc */
    private final ReentrantLock putLock = new ReentrantLock();

ArrayBlockingQueue ,读写就一把锁,效率低

     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();
    }

相关文章

网友评论

      本文标题:Day 35 BlockingQueue 实战及其原理

      本文链接:https://www.haomeiwen.com/subject/rluoertx.html