线程安全的集合类
来源:互联网 发布:ubuntu 脚本使用教程 编辑:程序博客网 时间:2024/05/16 05:58
java中常用的线程安全集合类
java.util.Hashtable
HashTable的实例中有两个参数影响其性能:初始容量和加载因子
初始容量:Hash表创建时的容量
加载因子:对hash表在其容量自动增加之前可以达到多满的一个尺度,通常默认是0.75
Hashtable 的函数都是同步的,意味着它是线程安全的。它的key和value都不可以为null。此外,hashtable中的映射不是有序的。
线程安全原理–源码如下
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable { private transient Entry<?,?>[] table; public synchronized V put(K key, V value) { ....此处省略实现 } public synchronized V remove(Object key) { ....此处省略实现 } public synchronized void putAll(Map<? extends K, ? extends V> t) { ....此处省略实现 } public synchronized V get(Object key) { ....此处省略实现 } public synchronized void clear() { ....此处省略实现 }}
从源码中可以看出,hashtable提供的几个主要方法,每个方法本身都是synchonizedde ,不会出现两个线程同时对数据进行操作的情况,因此是线程安全的
java.util.concurrent.ConcurrentHashMap
ConcurrentHashMap 继承AbstractMap 实现ConcurrentMap
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable { static class Segment<K,V> extends ReentrantLock implements Serializable { private static final long serialVersionUID = 2249069246763182397L; final float loadFactor; Segment(float lf) { this.loadFactor = lf; } }}
java.util.concurrent.CopyOnWriteArrayList
CopyOnWriteArrayList 中的set、add、remove等方法,都使用了ReentrantLock的lock来加锁,unlock来解锁
当增加元素的时候使用Arrays.copyOf()来拷贝副本,在副本上增加元素,然后改变原来引用的指向副本。读操作不需要加锁,因此,CopyOnWriteArrayList类是一个线程安全的List接口实现,这对于读操作远远多于写操作的应用非常适合,特别是在并发的情况下,可以提供高性能的并发读取,并保证读取的内容一定是正确的,不受多线程并发问题的影响。
public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { final transient ReentrantLock lock = new ReentrantLock(); private E get(Object[] a, int index) { return (E) a[index]; }}
java.util.concurrent.CopyOnWriteArraySet
原理同CopyOnWriteArrayList
CopyOnWrite机制介绍
CopyOnWrite容器即写是复制的容器。通俗的理解就是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素后,再将原容器的引用指向新的容器。这样做的好处就是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素
所以,CopyOnWrite容器也是一种读写分离的思想。读和写不容的容器。
我们从CopyOnWriteArrayList之前的分析和源码中可以看出,ArrayList里添加元素,在添加的时候是需要加锁的,否则多线程写的时候会copy出多个副本出来
读的时候不需要加锁,如果都的时候有多线程正在像ArrayList中添加数据,还是会读到旧的数据,因为写的时候不会锁住旧的ArrayList
1、使用场景:读多写少
2、使用注意点:
a、减少扩容开销;b、使用批量添加
缺点:
a、内存占用问题
b、数据一致性问题
Vector
与ArrayList不同,Vector中的操作是线程安全的,他是利用synchronized同步显示锁的机制实现的,实现机制类似Hashtable
StringBuffer和StringBuilder
StringBuffer:线程安全,效率不高,方法上使用synchronized实现线程安全机制
StringBuilder:线程不安全,效率相对高
- 线程安全的集合类
- 线程安全的集合类
- 线程安全的集合
- 线程安全的集合
- 线程安全集合类
- c#集合类的线程安全
- c#集合类的线程安全
- c#集合类的线程安全
- 集合框架的线程安全类
- java线程安全的集合类
- 线程安全的并发集合类
- 自定义线程安全的集合类
- java集合框架,线程安全的类
- .NET的ConcurrentDictionary,线程安全集合类
- Java集合中线程安全的类
- c#集合类的线程安全
- c#集合类的线程安全
- 14.7 线程安全的集合
- Kafka集群操作指南
- 三.如何使用组合命令(Compound Command)
- java web实现img读取盘符下的图像
- poj 2524Ubiquitous Religions (并查集)
- 编写程序打印空心菱形
- 线程安全的集合类
- MySQL性能优化总结
- MySQL技术内幕 InnoDB存储引擎(一)
- Java多线程之并发工具类之CyclicBarrier
- mac mobile angular ui安装
- nodejs 文件操作
- JAVA修饰词详解:public、protected、default、private
- JAVA设计模式(原型模式)
- ssm sql 例子(freemarker+jsp)