Java多线程之同步类容器与并发容器
来源:互联网 发布:没文凭自学编程找工作 编辑:程序博客网 时间:2024/05/01 23:55
同步容器类
同步容器类包括Vector和HashTable,而且是早期JDK的一部分,这些同步的封装器类是由Collections.synchronizedxxx等工厂方法创建的。例如 Map<String,String> map =Collections.synchronizedMap(new HashMap<String,String >());
HashMap本来不是线程安全的,但是上面的map就是线程安全的,
在源码中可以看到,map的方法都被synchronized修饰了。
同步容器类都是线程安全的,但在某些情况下可能需要额外的客户端锁来保护复合操作,比如:迭代以及条件运算,在同步类容器中,这些复合操作在没有客户端加锁的情况下是仍然是线程安全的,但是当其他线程并发的修改容器时,他们可能会出现异常。
public static Object getLat(Vector list){ int lastIndex =list.size()-1; return list.get(lastIndex); } public static void deleteLast(Vector list){ int lastIndex =list.size()-1; list.remove(lastIndex); }
上面的代码,如果线程A在包含10个元素的Vector上调用getLast,同时线程B在同一个Vector上调用deleteLast,这时可能会抛出ArrayIndexOutOfBoundsException异常
.
想要避免上面异常的出现,可以再迭代过程中持有容器的锁。
synchronized (vector){ for(int i=0;i<vector.size();i++){ doSomrthing(vector.get(i)) }}
然而在迭代期间对容器加锁,并不是一个很好的方法,例如,某些线程在可以访问容器之前,必须等待迭代过程结束,如果容器的规模很大,那么这些线程就会长时间得到等待,这可能会产生死锁,极大地降低了脱吐量和CPU的利用率。
同步类容器最大的缺点是不支持高并发!性能差!!
并发容器
Java5.0提供了多种并发容器类来改进同步容器的性能。同步类容器将所有对容器状态的访问都串行化,以实现它们的线程安全性。这种方法的代价是严重降低并发性!!!
Java5.0中增加了ConcurrentHashMap
用来代替同步且基于散列的Map,以及CopyOnWriteArrayList
,CopyOnWriteArraySet
来代替同步的List和Set。
ConcurrentHashMap
同步类容器在执行每个操作的期间都持有一把锁。当遍历很长的链表并且在某些或者全部的元素上调用equals方法会花费很长的时间,而其他线程在此期间都不能访问该容器。
与HashMap一样,ConcurrentHashMap也是一个基于散列的Map,但是他使用了一种完全不同的加锁机制来提供更高的并发性和伸缩性。ConcurrentHashMap使用的是一种粒度更细的加锁机制来实现更大数据的共享,这种机制成为分段锁。
在这种机制中,任意数量的线程可以并发的访问容器。ConcurrentHashMap带来的效果是在并发情况下实现更高的吞吐量,而在单线程环境下也只是损失非常小的性能。
ConcurrentHashMap提供的迭代器不是抛出ConcurrentModificationException异常。
CopyOnWriteArrayList
CopyOnWriteArrayList用来代替同步的List在某些情况下,它提供了更好的并发性能,并且在迭代期间不需要对容器进行加锁或复制,
“写入时复制(Copy-On-Write)”容器的线程安全性在于只要发布一个正确的不可变得对象,那么在访问该对象时就不需要进一步的同步。
/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { //得到array的引用 Object[] elements = getArray(); int len = elements.length; //复制一个数组并且长度加一(添加元素) Object[] newElements = Arrays.copyOf(elements, len + 1); //保存新添加的元素 newElements[len] = e; //将新数组对象赋值给array setArray(newElements); return true; } finally { lock.unlock(); } }
容器中的array就是存储元素的容器,
private transient volatile Object[] array;
CopyOnWriteArrayList适用于读操作多写操作少的场景。
- Java多线程之同步类容器与并发容器
- Java多线程之同步容器与并发容器
- java 多线程 同步类容器与并发类容器
- java多线程(9)--同步类容器和并发类容器
- 【Java 并发】浅析同步容器类与并发容器类
- Java同步容器与并发容器
- 同步类容器与并发类 容器
- 同步类容器与并发容器
- java线程安全之同步类容器与并发类容器(十二)
- java多线程(七) 之 同步容器类
- Java同步并发容器类
- Java并发编程规则:同步容器与并发容器
- java并发编程学习:同步容器与并发容器
- 菜鸟之路——Java并发(五)同步容器与并发容器
- java-并发-同步容器
- JAVA并发-同步容器和并发容器
- java并发:同步容器&并发容器
- java并发编程之同步容器
- vue中实现滚动加载更多
- Redis常用数据类型介绍、使用场景及其操作命令
- CONNECT BY理解
- Android线程—Volatile关键字(一)
- mxnet学习序列
- Java多线程之同步类容器与并发容器
- H264编码和解码的问题——b intra refresh
- spark-大表join优化方案
- MVVM
- 删除已使用过且无法删除的替代
- Vue component-based application structure
- split
- linux中获取/更新Let’s encrypt 证书的脚本
- Adobe cc 2017 全系列软件下载 附破解安装教程