[Java concurrent][Collections]
同步容器类
- 同步容器类包括Vector和Hashtable,二者是早期JDK的一部分。以及一些在JDK1.2中添加的可以由Collections.synchronizedXxx等工厂方法创建的。
- 这些类实现线程安全的方式是,将它们的状态封装起来,并对每个公有方法都进行同步(synchronized),使得每次只有一个线程能访问容器的状态。
- 同步容器类在一些情况下,可能需要额外的客户端加锁来保护复合操作。
eg:public static Object getLast(Vector list) {
synchronized(list) {
int lastIndex = list.size() - 1;
return list.get(lastIndex);
}
}比如在迭代的时候,需要加锁,那就会严重降低并发。这时候也可以考虑通过“克隆”容器的方法。通过考虑容器的大小、操作的开销等因素来抉择。
- 在迭代过程中,如果对容器进行修改就会抛出ConcurrentModificationException的异常(该异常即使是在单线程也可以抛出,即当对象直接从容器中删除而非使用Iterator.remove()时)。
The iterators returned by the iterator method of the collections
* returned by all of this class's "collection view methods" are
* fail-fast: if the Hashtable is structurally modified at any time
* after the iterator is created, in any way except through the iterator's own
* remove method, the iterator will throw a
* ConcurrentModificationException
Hashtable
- An instance of
Hashtablehas two parameters that affect its performance: initial capacity and load factor.
The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. 因为在有冲突的时候需要顺序查找。
The load factor (default 0.75) is a measure of how full the hash table is allowed to get before its capacity is automatically increased. - variables are private;
public function are synchronized - 用synchronized来锁住整张表来实现线程安全,即每次锁住整张表让线程独占。
synchronizedList
- static function of Collections
- Returns a synchronized (thread-safe) list backed by the specified list.
- In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.
- 实际上就是把原生collections封装在一个SynchronizedCollection内部,这个类有一个
final Object mutex; // Object on which to synchronized
其内部的方法都是类似
public boolean contains(Object o) { synchronized(mutex) {return c.contains(o); }}
并发容器
- 同步容器是通过将操作串行化来实现它们的线程安全性,因而严重降低了并发性。
- Java5.0提供了多种容器来改进同步容器的性能。比如
- 增加了ConcurrentHashMap来替代同步且基于散列的Map
- CopyOnWriteArrayList用于在遍历操作为主要操作的情况下代替同步的List。
- 增加了对一些常见复合操作的支持,如“若没有则添加”、替换以及有条件删除等。
java.util.concurrent
- refer javadoc.
- java.util.concurrent: Utility classes commonly useful in concurrent programming.
Memory Consistency Properties
- 首先,你需要知道happens-before,可以参考link。
- The methods of all classes in java.util.concurrent and its subpackages extend these guarantees to higher-level synchronized. In particular:
- Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.
- Actions in a thread prior to the submission of a
Runnableto anExecutorhappen-before its execution begins. Similarly forCallablessubmitted to anExecutorService. - Actions taken by the asynchronous computation represented by a
Futurehappen-before actions subsequent to the retrieval of the result viaFuture.get()in another thread. - Actions prior to "releasing" synchronizer methods such as
Lock.unlock,Semaphore.release, andCountDownLatch.countDownhappen-before actions subsequent to a successful "acquiring" method such asLock.lock,Semaphore.acquire,Condition.await, andCountDownLatch.awaiton the same synchronizer object in another thread. - For each pair of threads that successfully exchange objects via an
Exchanger, actions prior to theexchange()in each thread happen-before those subsequent to the correspondingexchange()in another thread. - Actions prior to calling
CyclicBarrier.awaitandPhaser.awaitAdvance(as well as its variants) happen-before actions performed by the barrier action, and actions performed by the barrier action happen-before actions subsequent to a successful return from the correspondingawaitin other threads.
ConcurrentHashMap
- Hashtable存在的问题是:在每个方法上都加锁而降低了并发。
ConcurrentHashMap采用的solution就是使用更细粒度的加锁机制来实现更大程度的共享,即分段锁(Lock Striping)。具体的原理是:
内部使用Segment来表示这些不同的部分,每个段其实就是一个小的hashtable,它们有自己的锁。只要修改操作发生在不同的段上,就可以并发进行。【The table is internally partitioned to try to permit the indicated number of concurrent updates without contention.】
有的方法需要跨段,比如size()和contains(),它们可能需要锁住整张表,这就需要按顺序锁定所有表,操作完毕后,又按顺序释放所有段的锁。 - ConcurrentHashMap在线程安全地基础上提供了更好的并发写能力,但是降低了对读一致性的要求。(感觉像CAP)
- 实现上,大量利用了volatile,final,CAS(Compare and Swap)等lock-free技术来减少锁竞争对性能的影响。
Source Code
- TBD...
[Java concurrent][Collections]的更多相关文章
- Java中编写线程安全代码的原理(Java concurrent in practice的快速要点)
Java concurrent in practice是一本好书,不过太繁冗.本文主要简述第一部分的内容. 多线程 优势 与单线程相比,可以利用多核的能力; 可以方便的建模成一个线程处理一种任务; 与 ...
- java中Collections.sort排序详解
Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f, ...
- Java API —— Collections类
1.Collections类概述 针对集合操作 的工具类,都是静态方法 2.Collections成员方法 public static <T> void ...
- java concurrent包的学习(转)
java concurrent包的学习(转) http://my.oschina.net/adwangxiao/blog/110188 我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常 ...
- How to Create a Java Concurrent Program
In this Document Goal Solution Overview Steps in writing Java Concurrent Program Template ...
- Java Concurrent Topics
To prevent Memory Consistency Errors(MCEs), it is good practice to specify synchronized class specif ...
- Java中Collections的min和max方法
方法一 public static <T extends Object & Comparable<? super T>> T min(Collection<? e ...
- java.lang.Collections
java.lang.Collections 此类完全由在collection上进行操作或返回 collection 的静态方法组成.也就是说Collections提供了对Collection集合操作的 ...
- java.util.Collections.copy():列表List浅拷贝
今天同事问我怎样将一个列表(list1)拷贝到另一个列表(list2),然后修改新的列表(list2)不会影响到旧的列表(list1),想了一想,这是深拷贝啊. 可是,除了循环new还有别的办法吗,想 ...
随机推荐
- git删除文件夹
git rm 要删除的文件夹 -r -f git commit -m 'del config' git push 使用场景,删除test文件夹,本来在码云上,正常的文件夹右击会出现 ...
- java日期和时间Date、Calendar、SimpleDateFormat
1 时间和日期 1.1 日期类Date和格式化SimpleDateFormat 日期使用过程中需要将日期Date对象转化为字符串,或者将字符串形式的日期转化为日期Date对象.可 ...
- hive中控制文件生产个数
在有些时候,想要控制hql执行的mapper,reducer个数,reducer设置过少,会导致每个reducer要处理的数据过多,这样可能会导致OOM异常,如果reducer设置过多,则会导致产生很 ...
- DS博客作业01--日期抽象数据类型设计与实验
1.思维导图及学习体会(2分) 1.1第一章绪论知识点思维导图 1.2 学习体会 2.大作业作业内容 (6分) 2.1 设计日期的ADT类型(1分) ADT DATE{ 数据对象:D={year,mo ...
- ZJOI2019Day1AFO记
先去看了看T3,发现暴力DP就是n^3的,于是不妨先写一个,写完n^3就9:30多了..有点慌去看看T1,太鬼畜了,还是先写个n=5压压惊...写了一年,在11:00写完并检查(?)了n=5.然后去看 ...
- 菜鸡学C语言之寻根溯源
题目描述 Mogg最近翻了翻自己家的族谱,想康康祖先是谁.但是族谱因为年久失修太乱了,他现在只整理出来了一系列父子关系,你能帮他找一找直系亲属中辈分最大的一位吗?(即父亲的父亲的父亲……) 输入 第1 ...
- word中一页中添加两种不同的页码
,在文档编写的过程中,可能一个页面需要编写两个不同的页码,举个例子,在页脚有一个页码是整个文档的页码,页眉有一个页码,是每个章节的页码: 设置如下: 此处选中这个图标是为了能够看到分节符和其他的符号 ...
- 调用 js 生成图片二维码
一.js 生成二维码: 首先,需要引用 jQuery 和 jquery.qrcode.js.然后: //生产二维码 $("#qrcodeCanvas").qrcode({ rend ...
- 【Python】Scrapy基础
一.Scrapy 架构 Engine(引擎):负责 Spider(爬虫).Item Pipeline(管道).Downloader(下载器).Scheduler(调度器)中的通讯和数据传递. Sche ...
- learning makefile foreach