目录

目标

List、Set、Queue

ArrayList

存储数据结构:数组。
扩容:当前size+1>数组长度,扩容长度为之前的1.5倍。Arrays.copyof(),将数据拷贝到新的数组。
使用注意:遍历时,无法修改添加值,由于有版本号,modcount。
线程不安全。

CopyOnWriteArrayList

CopyOnWrite思想
copy一份数组提供给写线程,然后在将数据进行切换。
在这里插入图片描述
CopyOnWriteArrayList是CopyOnWrite思想的实现。
数据结构:Object[] array;
基本原理:任意读,互斥写;用于读极多,写极少场景。
作用:读多写少情况下,会阻塞情况。
缺点:不能完全保证数据的一致性,有一定延时;需要全量的copy数据,要保证内存足够大;存储数量太大,会导致GC。
在这里插入图片描述

Set集合

set:元素不重复,无序,不保证顺序。

HashSet

存储结构:map-》hashmap
基本原理:利用hashmap原理实现。

CopyOnWriteArraySet

如何保证不重复:简单判断,存在就不添加,不存在就添加。

ConcurrentSkipListSet

key值有序。

Queue API

队列:先进先出,不绝对。
栈:先进后出。
API方法分类:抛异常、阻塞(一直阻塞,直到数据操作成功)、非阻塞。
在这里插入图片描述

ArrayBlockingQueue

特性:数组的数据结构、实现阻塞、线程安全、不能扩容、长度固定。
阻塞实现原理:使用ReentrantLock的Condition的await方法,将当前线程挂起,即线程状态进入waiting状态,使用两个Condition相互唤醒。
数组实现先进先出基本原理:循环数组-》使用2个index,对数组进行循环的操作,一个index为写的标记,一个为读的标记。

LinkedBlockingQueue

特性:链表数据结构、实现阻塞、线程安全、无边界。
有两把锁,put和take。

ConcurrentLinkedQueue

特性:在并发场景下,效率更高、链表的数据结构、 非阻塞,没有实现阻塞方法(put、take)。
自旋和阻塞: 自旋线程处于Runnalbe状态,阻塞处于waiting或blocked状态。
offer();->使用自旋+CAS操作入队列
poll();
不再 使用锁的方式来实现线程安全,通过CAS来实现无锁编程使效率更高,主要CAS操作链表头部和尾部。

SynchronousQueue同步队列

特性:没有容量。
1、take会阻塞,直到取到元素
2、put时会阻塞,直到被get
3、若没有take方法阻塞等待,offer的元素可能会丢失
4、poll取不到元素,就返回null,如果正好有put被阻塞,可以取到
5、peek 永远只能取到null,不能让take结束阻塞
使用场景:缓存线程池,由同步队列来实现的。

PriorityBlockingQueue优先级队列

特性:并不是按照先进先出的顺序,会将数据的顺序做个排序,可以自己指定数据的优先级(比较器),自己定义比较规则。
基本使用

public class Demo4_PriorityBlockingQueue3 {
    public static void main(String args[]){
        PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(5, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int num1 = o1.age;
                int num2 = o2.age;

                if (num1 > num2)
                    return 1;
                else if (num1 == num2)
                    return 0;
                else
                    return -1;
            }
        });
        queue.put(new Student(10, "enmily"));
        queue.put(new Student(20, "Tony"));
        queue.put(new Student(5, "baby"));

        for (;queue.size() >0;){
            try {
                System.out.println(queue.take().name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Student{
    public int age;
    public String name;

    public Student(int age, String name){
        this.age = age;
        this.name = name;
    }
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐