并发容器类list_set_queue
目录目标ArrayListCopyOnWriteArrayListSet集合HashSetCopyOnWriteArraySetConcurrentSkipListSetQueue APIArrayBlockingQueueLinkedBlockingQueueConcurrentLinkedQueueSynchronousQueue同步队列PriorityBlocki...
目录
- 目标
- ArrayList
- CopyOnWriteArrayList
- Set集合
- HashSet
- CopyOnWriteArraySet
- ConcurrentSkipListSet
- Queue API
- ArrayBlockingQueue
- LinkedBlockingQueue
- ConcurrentLinkedQueue
- SynchronousQueue同步队列
- PriorityBlockingQueue优先级队列
目标
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;
}
}
更多推荐
所有评论(0)