多线程与高并发7-容器

在这里插入图片描述
Queue队列:主要就是为高并发而存在,有进有出。
Deque双关队列:头和尾都可以存取
BlockingQueue阻塞队列:
PriorityQueue优先队列:按照顺序先入先出
DelayQueue延迟队列:队列中的对象只有到期之后才能被取走

HashTable,Vector

一代同步容器,所有的方法均上锁,基本不用

HashTable,HashMap,SynchroizedHashMap,ConcurrentHashMap

HashTable:JDK1.0时代,所有的方法都上了锁,性能较差
HashMap:效率高却无锁
SynchronizedHashMap:为解决HashMap无锁的问题,Collections工具类提供的转换方法。HashTable直接给方法上锁,这个是通过一个对象进行上锁效率稍高。

Collections.synchronizedMap(new HashMap<>);

ConcurrentHashMap:并发table

在写效率上来说,主要还是要看并发数和线程数,如果小并发情况下,sync式的map并不一定比ConcurrentHashMap低。(sync锁升级)。高并发情况下使用ConcurrentHashMap.
在读效率上,ConcurrentHashMap比HashTable和SyncTable效率高数十倍

ArrayList,Vector,Queue

ArrayList线程不安全,多个线程访问产生超卖现象
Vector线程安全,但所有的方法都上了锁
ConcurrentLinkedQueue在多线程条件下,如果没有不能重复线程,尽量使用Queue。queue提供了很多对多线程友好的api [ offer() peek() poll() ]
对于blockingqueue [ put() take() ]

Queue q = new ConcurrentLinkedQueue<>();
q.add();
q.poll();

ConcurrentHashMap,ConcurrentSkipListMap

非线程同步:hashMap,treeMap(红黑树排序,查询速度快)
线程同步:ConcurrentHashMap,ConcurrentSkipListMap(跳表,CAS实现于Tree太复杂,通过跳表实现。也是redis zset底层)
在这里插入图片描述
跳表结构,底层仍是链表(排序),选举出父节点,父节点们仍是链表结构(并行链表),如果元素较多再次选举。查询时,通过父节点之间的范围,最终获得到该节点。
效率要比链表快很多(O(n),O(logn))

CopyOnWriteArrayList,CopyOnWriteArraySet

应用:多线程并发,写操作少读操作多的情况。写的时候sync,通过Arrays.copyOf交换新增元素后的新数组。读时没有加锁(除新增元素,其他元素一模一样没必要加锁)
写时复制,在新增元素时,复制一个Array将元素放到最后的位置,然后指向新的地址。

BlockingQueue

LinkedBlockingQueue无界的 (不超过Integer.MAX_VALUE)
ArrayBlockingQueue有界的
DelayQueue在时间上排序
Synchronousqueue在两个线程间传递任务
Transferqueue以上q集合

Queue常用方法:

offer()添加元素,返回是否添加元素成功的返回值
peek()取出元素,并不会去掉元素
poll()取出元素,并且去掉元素

BlockingQueue常用方法(天生实现生产消费者):

put()放入元素,如果满了就会等待
take()取出元素,如无元素可取,将会阻塞

ArrayBlockingQueue

构造方法可以确定大小,到达阈值后:
put方法执行,将不会添加元素,并阻塞;
add方法执行,将抛出异常,full queue;
offer方法执行,不会添加元素,返回值false,构造方法可传入时间来尝试添加

DelayQueue

可根据时间进行执行任务,定时任务调度

PriorityQueue

不按照插入顺序取出,通过优先级排序,最小的先出

SynchronusQueue

容量为零,作用不是用来装载元素的,而是给其他线程下达任务的。

使用add()会异常,因为容量为0,不能够添加元素。只能使用put()进行阻塞操作,等待take()取走元素

TransferQueue

LinkedTransferQueue
transfer(“test”); 添加元素后,阻塞,等待取走元素。
场景:必须确定消费者取走元素。

发布了25 篇原创文章 · 获赞 0 · 访问量 580

猜你喜欢

转载自blog.csdn.net/RaymondCoder/article/details/105104367