Java集合大致可分为Set、List和Map三种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合。Java 5之后,增加了Queue体系集合,代表一种队列集合实现。

JDK1.5版本中,加入java.uill.concurrent包,其中包含集合的线程安全方式的实现。本文仅探讨concurrent包下面的Map接口实现。

1. concurrent包下面Map子接口、类框架图

2. ConcurrentMap接口、ConcurrentHashMap类

2.1 它是什么?

ConcurrentHashMap是一个线程安全的哈希表,它的主要功能是提供了一组和HashMap功能相同但是线程安全的方法。ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁。

2.2 它的工作原理?

ConcurrentHashMap为了提高本身的并发能力,在内部采用了一个叫做Segment的结构,一个Segment其实就是一个类Hash Table的结构,Segment内部维护了一个链表数组,我们用下面这一幅图来看下ConcurrentHashMap的内部结构:

从上面的结构我们可以了解到,ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部,因 此,这一种结构的带来的副作用是Hash的过程要比普通的HashMap要长,但是带来的好处是写操作的时候可以只对元素所在的Segment进行加锁即可,不会影响到其他的 Segment,这样,在最理想的情况下,ConcurrentHashMap可以最高同时支持Segment数量大小的写操作(刚好这些写操作都非常平均地分布在所有的Segment上),所以,通过这一种结构,ConcurrentHashMap的并发能力可以大大的提高。

2.3 它实现的ConcurrentMap接口方法:

  • V putIfAbsent(K key, V value): 如果指定键已经不再与某个值相关联,则将它与给定值关联;推荐使用该方法,而不是使用Map接口的put()方法。
  • boolean remove(Object key, Object value): 只有目前将键的条目映射到给定值时,才移除该键的条目。
  • boolean replace(K key, V oldValue, V newValue): 只有目前将键的条目映射到给定值时,才替换该键的条目。
  • V replace(K key, V value): 只有目前将键的条目映射到某一值时,才替换该键的条目。

2.4 它实现的Map接口主要方法:

  • V get(Object key): 返回此表中指定键所映射到的值;此操作不涉及到锁,也就是说获得对象时没有使用锁。
  • Set<Map.Entry<K,V>> entrySet(): 该视图的返回的 iterator 是一个“弱一致(weakly consistent)”的迭代器,它从来不会抛出 ConcurrentModificationException,并且确保可遍历迭代器构造时存在的元素,此外还可能(但并不保证)反映构造后的所有修改。

2.5 ConcurrentMap接口的putIfAbsent()与remove()方法详解:

putIfAbsent() 方法用于在 map 中进行添加。这个方法以要添加到 ConcurrentMap 中的键的值为参数,就像普通的 put() 方法,但是只有在 map 不包含这个键时,才能将键加入到 map 中。如果 map 已经包含这个键,那么这个键的现有值就会保留。 putIfAbsent() 方法是原子的。等价于下面的代码(除了原子地执行此操作之外):

   if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);

remove() 方法有两个参数:键和值。在调用时,只有当键映射到指定的值时才从 map 中删除这个键。如果不匹配,那么就不删除这个键,并返回 false。如果值匹配键的当前映射内容,那么就删除这个键,这个方法是原子性的。这种操作的等价源代码(除了原子地执行此操作之外):

if (map.get(key).equals(value)) {
map.remove(key);
return true;
} else return false;

由此可以看出,java.util.concurrent.ConcurrentMap 接口和 ConcurrentHashMap 实现类可以实现只能在键不存在时将元素加入到map中;只有键存在且映射到特定值时才能从map中删除一个元素。

Java:concurrent包下面的Map接口框架图(ConcurrentMap接口、ConcurrentHashMap实现类)的更多相关文章

  1. Java:concurrent包下面的Collection接口框架图( CopyOnWriteArraySet, CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  2. JAVA concurrent包下Semaphore、CountDownLatch等用法

    CountDownLatch 跟join的区别 CountDownLatch用处跟join很像,但是CountDownLatch更加灵活,如果子线程有多个阶段a.b.c; 那么我们可以实现在a阶段完成 ...

  3. List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedList Set有两个实现类:HashSet和LinkedHashSet AbstractSet实现了Set

    List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedListSet有两个实现类:HashSet和LinkedHashSetAbstractS ...

  4. Java并发机制(8)--concurrent包下辅助类的使用

    Java并发编程:concurrent包下辅助类的使用 整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3920397.html 1.CountDown ...

  5. java concurrent包的学习(转)

    java concurrent包的学习(转) http://my.oschina.net/adwangxiao/blog/110188 我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常 ...

  6. java.io 包下的类有哪些 + 面试题

    java.io 包下的类有哪些 + 面试题 IO 介绍 IO 是 Input/Output 的缩写,它是基于流模型实现的,比如操作文件时使用输入流和输出流来写入和读取文件等. IO 分类 传统的 IO ...

  7. java.util.concurrent包下集合类的特点与适用场景

    java.util.concurrent包,此包下的集合都不允许添加null元素 序号 接口 类 特性 适用场景 1 Queue.Collection ArrayBlockingQueue 有界.阻塞 ...

  8. Java:集合,Map接口框架图

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  9. java Concurrent包学习笔记(四):BlockingQueue

    一.BlockingQueue概述 1.阻塞的含义 BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞.被阻塞的情况主要有如下两种: ,当一个线程对 ...

随机推荐

  1. Python两个变量的值进行交换的方法

    Python两个变量的值进行交换的方法 使用第三方变量: '''这是第一种赋值方法,采用第三方变量''' c = a a = b b = c 使用两个变量: '''使用两个变量''' a = a+b ...

  2. Oracle单引号双重角色——字符串引用与转义

    单引号双重角色——字符串引用与转义      在ORACLE中,单引号有两个作用,一是字符串是由单引号引用,二是转义,开始学习时动态构成SQL时经常不解.单引号的使用是就近配对,即就近原则.而在单引号 ...

  3. Java ReEntrantLock 之 Condition条件(Java代码实战-002)

    import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurren ...

  4. 为wget命令设置代理

    实验环境:ubuntu 12.04 LTS  goagent 方法一.在环境变量中设置代理 export http_proxy=http://127.0.0.1:8087 方法二.使用配置文件 为wg ...

  5. sql如何通过当前日期获取上周,上上周,上上上周的起始日期(周一_周七)

    当前时间周的起始日期(以周一为例)select DATEADD(week,DATEDIFF(week,0,getdate()),0)上周起始:select dateadd(week,-1,DATEAD ...

  6. python之模块base64

    # -*- coding: cp936 -*- #python 27 #xiaodeng >>> help(base64) #用来作base64编码解码 FUNCTIONS #函数( ...

  7. 转载:mysql添加用户、删除用户、授权、修改密码

    mysql添加用户.删除用户.授权.修改密码等 MySql中添加用户,新建数据库,用户授权,删除用户,修改密码1.新建用户. //登录MYSQL @>mysql -u root -p @> ...

  8. 关于通信的关键词UDP/(TCP/IP)/IPC/RPC/.NET Remoting/WebService/WCF/Http 系列

    OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行实践: ...

  9. 网站PV、UV以及查看方法

    网站PV.UV以及查看方法 一.名词解释 PV:PV 是Page Views的缩写,即页面浏览量,用户每一次对网站中的每个网页访问均被记录一次.注意,访客每刷新一次页面,pv就增加一次. UV:UV是 ...

  10. Mybaits 使用多数据库源错误 --MapperScannerConfigurer配置

    我在配置文件里面配置了一个数据源,数据源参数是根据配置文件加载.数据源在mybaits和自定义数据工具类中使用,但是启动工程后,报错如下:  ### Cause: org.springframewor ...