ConcurrentMap与CopyOnWrite容器
ConcurrentMap接口下有两个重要的实现:
ConcurrentHashMap
ConcurrentSkipListMap(支持并发排序功能,弥补ConcurrentHashMap)
ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的HashTable,它们有自己的锁。只要多个修改操作发生在不同的段上,他们就可以并发进行。把一个整体分成了16个小段(Segment)。也就是最高支持16个线程的并发修改操作。这也是在多线程场景时减小锁的粒度从而降低锁竞争的一种方案。并且代码中大多共享变量使用volatile关键字声明,目的是第一时间获取修改的内容,性能非常好。
下面 通过图形来对比一下
先说明一张原来的形式的图:

在t1线程执行写操作的时候,加入花费1s时间,在这1s的时间内,t2线程也来修改hashtable里面的其他参数的时候,t2线程只能在外面等待t1线程执行结束后,才能继续自己的操作。
再看一张ConcurrentMap执行此类情况的图形:

在t1线程操作的时候,t2线程可以操作ConcurrentMap的没t1操作的段(Segment),ConcurrentMap最高支持16个段,如果两个线程都是操作一个段(Segment),那没办法,只能等待t1执行完后,t2才能去执行。
Copy-On-Write
Copy-On-Write简称COW,是一种用于程序设计中的优化策略。
JDK里的COW容器有两种:CopyOnWriteArrayList和CopyOnWriteArraySet,COW容器非常有用,可以在非常多的并发场景中使用到。
什么是CopyOnWrite容器?
CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

这个容器在写入的时候,会copy一份,然后在新的里面进行修改,此时,如果有其他线程要去读取数据的时候,会去原来的里面去读取,在写线程写入完毕后,对应的指针会指向新的内存空间,这种方式适合读多写少的情况。
在多个写的过程中,jdk的底层是有锁的,只有在一个线程结束后,才允许另外一个线程去操作数据,不会出现数据不一致的现象。
下面看一个ConcurrentHashMap的里面一个比较有意思的方法,
public class UseConcurrentMap {
public static void main(String[] args) {
ConcurrentHashMap<String, Object> chm = new ConcurrentHashMap<String, Object>();
chm.put("k1", "v1");
chm.put("k2", "v2");
chm.put("k3", "v3");
chm.putIfAbsent("k4", "vvvv");
// for (Map.Entry<String, Object> me : chm.entrySet()) {
// System.out.println("key:" + me.getKey() + ",value:" + me.getValue());
// }
Iterator iter = chm.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry me = (Map.Entry) iter.next();
System.out.println("key:" + me.getKey() + ",value:" + me.getValue());
}
}
}
设想一个,这段代码的打印结果是什么?

putIfAbsent的用法是先判断ConcurrentHashMap里面是否存在这个key,如果不存在,就把key和对应的value放入ConcurrentHashMap中,如果存在,则不操作ConcurrentHashMap。 下面说一下这两个容器的缺点:
这两种模式只是提高了高并发中的性能,并不是说高并发项目中,用了这个容器就解决问题了,具体还是要看具体项目的场景及项目的代码设计。
ConcurrentMap与CopyOnWrite容器的更多相关文章
- 同步类容器和并发类容器——ConcurrentMap、CopyOnWrite、Queue
一 同步类容器同步类容器都是线程安全的,但在某些场景中可能需要加锁来保证复合操作. 符合操作如:迭代(反复访问元素,遍历完容器中所有元素).跳转(根据指定的顺序找到当前元素的下一个元素).条件运算. ...
- Copy-On-Write容器
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
- java多线程-Java中的Copy-On-Write容器
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
- Java再学习——CopyOnWrite容器
一,定义 CopyOnWrite容器即写时复制的容器.通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完 ...
- Java并发编程:CopyOnWrite容器的实现
Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...
- Java并发包中CopyOnWrite容器相关类简介
简介: 本文是主要介绍,并发容器CopyOnWriteArrayList和CopyOnWriteArraySet(不含重复元素的并发容器)的基本原理和使用示例. 欢迎探讨,如有错误敬请指正 如需转载, ...
- 聊聊并发-Java中的Copy-On-Write容器
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp78 聊聊并发-Java中的Copy-On-Write容器 Cop ...
- Java多线程:CopyOnWrite容器
一.什么是CopyOnWrite容器 CopyOnWrite容器即写时复制的容器.通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然 ...
- Java并发中的CopyOnWrite容器
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
随机推荐
- redis如何清除所有的key
redis比memcache好的地方之一,如果memcache,恐怕就得关掉重启了. 1 使用cli FLUSHDB 清除一个数据库,FLUSHALL清除整个redis数据. 2 使用shell re ...
- WDA-4-ALV按钮&ICON
1.ICON图标 AccessControlledArea (14x14) Activate (14x14) Active (14x14) AdaptationTechnical (14x14) Ad ...
- css样式表2
<head> <style type="text/css"> .main { height:42px; width:100%; text-align:cen ...
- RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介(转载)
RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介 今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. N ...
- Spark安装过程纪录
1 Scala安装 1.1 master 机器 修改 scala 目录所属用户和用户组. sudo chown -R hadoop:hadoop scala 修改环境变量文件 .bashrc , 添加 ...
- week6 10 后端backend server和mongoDB通信
0 之前我们maogoDB用的是在线的mlab 在线他们帮我们做好了model 也就是那个schma 其实python也有类似的包 帮我们定义这些model 但是呢 我们自己来做吧 用一个传统的意义上 ...
- FMS Dev Guide学习笔记(权限控制)
一.开发交互式的媒体应用程序 1.关于访问(权限)控制 当一个用户访问服务器的时候,默认情况下,他可以访问所有的流媒体文件和共享对象.但是你可以使用服务端ActionScript为流媒体文件和 ...
- springmvc文件上传功能
步骤: 1.在mvc配置文件中添加 2.在控制层的写法: 先在项目目录中添加一个文件夹 再在控制层写上传文件的代码(ps:图片保存在项目中的,并不是保存在文件服务器中) 上传文件的jsp 展示图片的j ...
- 吴裕雄 python神经网络(6)
import randomimport numpy as npnp.random.randint(0,49,3) ##required libarariesimport tensorflow as t ...
- LDA线性判别分析(转)
线性判别分析LDA详解 1 Linear Discriminant Analysis 相较于FLD(Fisher Linear Decriminant),LDA假设:1.样本数据服从正态分布,2 ...