欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java BlockingQueue阻塞队列

程序员文章站 2024-02-11 12:45:46
...

一、类结构图

Java BlockingQueue阻塞队列

二、实现类介绍

1. ArrayBlockingQueue

基于数组结构的有界阻塞队列(长度不可变);

2. LinkedBlockingQueue

基于链表结构的有界阻塞队列(默认容量 Integer.MAX_VALUE);

3. LinkedTransferQueue

基于链表结构的*阻塞/传递队列;

4. LinkedBlockingDeque

基于链表结构的有界阻塞双端队列(默认容量 Integer.MAX_VALUE);

5. SynchronousQueue

不存储元素的阻塞/传递队列;(也就是没有容量的队列。使用地方:线程池的核心容量满了 直接添加到线程直到达到最大线程池数量 后启用拒绝策略

Java BlockingQueue阻塞队列
Java BlockingQueue阻塞队列

6. PriorityBlockingQueue

支持优先级排序的*阻塞队列;

  1. DelayQueue

支持延时获取元素的*阻塞队列;

注:无锁采用CAS 也是线程安全的

队列 有界性 数据结构
ArrayBlockingQueue bounded 加锁 arraylist
LinkedBlockingQueue optionally-bounded 加锁 linkedlist
ConcurrentLinkedQueue unbounded 无锁 linkedlist
LinkedTransferQueue unbounded 无锁 linkedlist
PriorityBlockingQueue unbounded 加锁 heap
DelayQueue unbounded 加锁 heap

三、常用方法介绍

   public interface BlockingQueue<E> extends Queue<E> {
        /*抛异常系列*/
        boolean add(E e);
        E remove();
        E element();
        
        /*特定值系列*/
        boolean offer(E e);
        E poll();
        E peek();
        
        /*阻塞系列*/
        void put(E e) throws InterruptedException;
        E take() throws InterruptedException;

        /* 超时系列*/
        boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
        E poll(long timeout, TimeUnit unit) throws InterruptedException;

        /*其它方法*/
        int remainingCapacity(); //剩余容量
        boolean contains(0bject o); //是否包含给定元素
        boolean remove(object o); //移除与之匹配的第个元素
        int drainTo(Collection<? super E> c); //转移元素到给定集合,返回己转移的数量
        int drainTo(Collection<? super E> c, int maxElements); //限制最大转移数量
    }
失败抛出异常 失败返回false 阻塞方法 等待一定时间 失败返回false
Insert add(e) offer(e) put(e) offer(e, time, unit)
Remove remove( ) poll() take() poll(time,unit)
Examine element() peek() not applicable not applicable

四、实现方式

ArrayBlockingQueue: 数组+锁实现
LinkedBlockingQueue: 链表+锁实现
PriorityBlockingQueue: 堆 + 锁
DelayQueue:PriorityQueue + 锁

PriorityQueue: Heap = 完全二叉树 + 特性(小根堆:根比儿子小, 大根堆: 。。)

五、性能

1.锁的性能消耗

Java BlockingQueue阻塞队列

2.Single Writer Principle(单写原则)

1)若只有一个线程对资源进行写操作,无需CPU浪费管理资源争夺或上下文切换
2)多个线程如果同时写同一个资源,必有争夺,就需要用锁或乐观锁等堵塞方法
使用非阻塞:CAS
Java BlockingQueue阻塞队列

3. Cpu Cache层次优化

CPU 缓存(Cache Memory)是位于 CPU 与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。
高速缓存的出现主要是为了解决 CPU 运算速度与内存读写速度不匹配的矛盾,因为 CPU 运算速度要比内存读写速度快很多,这样会使 CPU 花费很长时间等待数据到来或把数据写入内存。
在缓存中的数据是内存中的一小部分,但这一小部分是短时间内 CPU 即将访问的,当 CPU 调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。
缓存是按行 (按行访问数组要比按列访问要快)
本文只是简要接收具体请参考其他博客如https://www.cnblogs.com/cyfonly/p/5800758.html

Java BlockingQueue阻塞队列

在内存中每行会进行缓存
如果cpu core1 写 cpu core2读

Java BlockingQueue阻塞队列

字段列表
Java BlockingQueue阻塞队列

在字段内存中分配的大小
Java BlockingQueue阻塞队列

同一个缓存行中一读 一写
Java BlockingQueue阻塞队列

解决方法

  1. 填充字段
  2. 填充内部类

Java BlockingQueue阻塞队列

4.其他优化策略

具体请百度

环形队列预分配,零GC
批量生产及消费
位运算,而非普通的求余取模(%) 有条件限制取末必须为2^N的数如 101%4 =101&(4-1)

相关标签: 并发编程