java多线程使用集合那点事

来源:互联网 发布:springboot源码分析 编辑:程序博客网 时间:2024/05/18 18:45
 
线程不安全的:

ArrayList
采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦

LinkedList
采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个链接的索引  但是缺点就是查找非常麻烦 要丛第一个索引开始

hashMap
HashMap可以让你将空值作为一个表的条目的key或value。HashMap中只有一条记录可以是一个空的key,但任意数量的条目可以是空的value。
这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将返回null。
如果有必要,用containKey()方法来区别这两种情况。

线程安全的:

如果非要使用list或map就要用 如下方法。

List list =java.util.Collections.synchronizedList(new ArrayList());
or
ConcurrentHashMap
ConcurrentHashMap是一个支持高并发的高性能的HashMap实现,它支持完全并发的读以及一定程度并发的写。

ConcurrentLinkedQueue
如果不需要阻塞队列,优先选择ConcurrentLinkedQueue;
ConcurrentLinkedQueue是Queue的一个安全实现.Queue中元素按FIFO原则进行排序.采用CAS非阻塞算法操作,来保证元素的一致性。
CAS算法实现,将当前节点的next指针指向val节点


ArrayBlockingQueue
如果需要阻塞队列,队列大小固定优先选择 ArrayBlockingQueue,
ArrayBlockingQueue是一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。
队列的头部 是在队列中存在时间最长的元素

LinkedBlockingQueue
队列大小不固定优先选择LinkedBlockingQueue;
由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,
其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。

PriorityBlockingQueue
如果需要对队列进行排序,选择 PriorityBlockingQueue;
PriorityBlockingQueue里面存储的对象必须是实现Comparable接口。队列通过这个接口的compare方法确定对象的priority。
规则是:当前和其他对象比较,如果compare方法返回负数,那么在队列里面的优先级就比较搞。

SynchronousQueue
如果需要一个快速交换的队列,选择SynchronousQueue;
SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take,反过来也一样。

DelayQueue
如果需要对队列中的元素进行延时操 作,则选择DelayQueue。



需求:假设有两个线程,先进先出原则,一个线程写,一个线程读,并删除最先的一个

方法:

1. LinkedList+synchronized

2.ConcurrentLinkedQueue

3.LinkedBlockingQueue

测试:

方法1和3差不多,LinkedBlockingQueue其实就是 LinkedList+synchronized

ConcurrentLinkedQueue在使用时,当两个线程都100%运算时,大部份资源都用在了写入上
0 0