juc学习笔记三-并发集合

1 ConcurrentLinkedQueue

HOPS延迟更新策略:

tail:当前tail节点的下一个节点为null时,只插入节点但是不更新tail;当前tail节点的下一个节点不为null时,才会定位真正的tail。

head:当前head的item不为null时只删除节点不更新head;当前head的item为null的时候才定位新的head。

HOPS策略减少了CAS更新,采用无锁的方式,可以达到更高的并发。

2 BlockingQueue和BlockingDeque

2.1 简介

BlockingQueue 阻塞队列,通常使用场景时是一个线程调用take方法获取队列头结点,一个线程调用put方法添加尾结点。该队列是有限的,当阻塞队列达到了上限,那么负责插入对象的线程就会发生阻塞。

在这里插入图片描述

对于队列达到上限不同方法有不同的处理方式:

在这里插入图片描述

抛异常:操作无法执行那么抛出异常。

特定值:操作无法执行则返回特定的值比如false。

阻塞:操作无法执行,那么当前线程被阻塞直到能够执行。

超时:操作无法立即执行,那么当前线程被阻塞直到能够执行,但是等待时间不会超过给定的值,如果超过就返回特定值。

BlockingDeque实现了BlockingQueue接口,该接口的实例时双向的,即两边都可以添加或删除。

2.2BlockingQueue的实现类

2.2.1 DelayQueue

DelayQueue实现了BlockQueue,延迟队列。其特征是入队之后的元素会按照一定顺序排序,并且每次头结点出队都会有延迟。

DelayQueue队列中每个对象都必须实现Delayed接口,getDelay方法的返回值是该对象剩余的延迟时间,当返回值<=0的时候说明已经过了延迟期可以出队了。

DelayQueue使用PriorityQueue类,PriorityQueue是一个优先队列,根据用户的comparTo方法对对象按照优先级进行排序。

代码示例:

public class DelayQueueExample {

    public static void main(String[] args) throws InterruptedException {
        DelayQueue<DelayObject> queue = new DelayQueue<DelayObject>();
        DelayObject object = new DelayObject("1",1);
        DelayObject object2 = new DelayObject("2",2);
        queue.put(object);
        queue.put(object2);
        DelayObject object3 = queue.take();
    }
}
public class DelayObject implements Delayed {

    private String name;
    private long time;
    private long startTime ;

    public DelayObject(String name,long time) {
        this.name = name;
        this.time = time;
        this.startTime = System.currentTimeMillis();
    }

    @Override
    public long getDelay(TimeUnit unit) {//DelayQueue的take方法源码中unit输入为TimeUnit.NANOSECONDS
        //这里的方法由程序员自己实现,我这里的逻辑是开始时间+延迟时间-当前时间,结果就是还需要延迟多久
        return unit.convert(this.startTime+time-System.currentTimeMillis(),TimeUnit.MILLISECONDS);
    }

    //实现compareTo方法是为了给队列中的对象排序
    @Override
    public int compareTo(Delayed o) {
        DelayObject ob = (DelayObject) o;
        //延迟时间越长优先级越低
        if(ob.time > this.time)
            return -1;
        else if(ob.time == this.time)
            return 0;
        return 1;
    }
}

2.2.2 ArrayBlockingQueue

ArrayBlockingQueue是有界的阻塞队列,依赖于数组实现,所以一旦初始化的时候设置了上限,就无法再改变。

测试示例:

public class BlockingQueueArrayExample {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue queue = new ArrayBlockingQueue(10);
        for(int i = 0;i<=10;i++){
//            queue.add(i); //超出范围会报错
            System.out.println(queue.offer(i));//超出返回会返回false
//            queue.put(i); //超出返回当前线程会被阻塞
        }
        Object ob = queue.take();
    }
}

2.2.3 LinkedBlockingQueue

LinkedBlockingQueue和ArrayBlockingQueue类似,不同的是LinkedBlockingQueue以链表的形式实现。

2.2.4 PriorityBockingQueue

PriorityBlockingQueue是有优先级的队列不能插入null。

2.2.5 LinkedTransferQueue

参考:JUC源码分析25-队列-LinkedTransferQueue_熊猫小牛牛的博客-CSDN博客_linkedtransferqueue

并发编程—— LinkedTransferQueue - 莫那-鲁道 - 博客园 (cnblogs.com)

2.3 BlockingDeque实现类

LinkedBlockingDeque是BlockingDeque的唯一实现类,这是一个双向队列可以从两端插入或者取出数据,当队列为空的时候,那么消费者线程会阻塞。

参考:JUC集合: BlockingQueue详解 | Java 全栈知识体系 (pdai.tech)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值