Java Maps
HashMap
是线程不安全的,主要对于写操作来说,两个以上线程同时写入Map会被互相覆盖。线程安全指的保证对同一个map的写入操作按照顺序进行,一次只能一个线程更改。比如向HashMap里put(key, value1)有可能key对应的是其他线程同时写入的value2
HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历,但两者的遍历速度是有差别的.
第一种:
// 效率高,以后一定要使用此种方式!
Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); }
第二种:
// 效率低,以后尽量少使用!
Map map = new HashMap(); Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object val = map.get(key); }
HashMap或者ArrayList边遍历边删除数据会报java.util.ConcurrentModificationException异常,需要用Iterator遍历删除。ConcurrentHashMap没有这种问题。
public void test() { Map bb = new HashMap(); bb.put("1", "wj"); bb.put("2", "ry"); Iterator it = bb.keySet().iterator(); while(it.hasNext()) { Object ele = it.next(); #bb.remove(ele); //wrong it.remove(ele); //right
} System.out.println("Success!");
}
对于ArrayList,不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。
//Right Iterator<String> it = a.iterator(); while(it.hasNext()){ String temp = it.next(); if(删除元素的条件){ it.remove(); } }
//Wrong List<String> a = new ArrayList<String>(); a.add("1"); a.add("2"); for (String temp : a) { if("1".equals(temp)){ a.remove(temp); } }
ConcurrentHashMap
public V get(Object key)不涉及到锁,也就是说获得对象时没有使用锁,保证读到最新的值
put、remove方法要使用锁,但并不一定有锁争用,原因在于ConcurrentHashMap将缓存的变量分到多个Segment,每个Segment上有一个锁,只要多个线程访问的不是一个Segment就没有锁争用,就没有堵塞,各线程用各自的锁,ConcurrentHashMap缺省情况下生成16个Segment,也就是允许16个线程并发的更新而尽量没有锁争用;
Iterator对象的使用,不一定是和其它更新线程同步,获得的对象可能是更新前的对象,ConcurrentHashMap允许一边更新、一边遍历,也就是说在Iterator对象遍历的时候,ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化,所以希望遍历到当前全部数据的话,要么以ConcurrentHashMap变量为锁进行同步(synchronized该变量),要么使用CopiedIterator包装iterator,使其拷贝当前集合的全部数据,但是这样生成的iterator不可以进行remove操作。
ConcurrentHashMap is much quicker than SynchronizedHashMap. ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
对ConcurrentHashMap边遍历边删除或者增加操作不会产生异常(可以不用迭代方式删除元素),因为其内部已经做了维护,遍历的时候都能获得最新的值。即便是多个线程一起删除、添加元素也没问题。
ConcurrentHashMap或者说所有的Map都不保证非原子性的操作,比如判断contains后再get的值可能已经改变,需要对整个Map加锁
You should use ConcurrentHashMap when you need very high concurrency in your project.
It is thread safe without synchronizing the whole map.
Reads can happen very fast while write is done with a lock.
There is no locking at the object level.
The locking is at a much finer granularity at a hashmap bucket level.
ConcurrentHashMap doesn’t throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it.
ConcurrentHashMap uses multitude of locks
HashTable
线程安全,但是对整个Map上锁,读和写都需要同步,在高竞争环境下效率很低,有Scalability 的问题
HashMap
Note that this implementation is not synchronized. If multiple threads access a hashmap concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map
SynchronizedHashMap
Synchronization at Object level.
Every read/write operation needs to acquire lock.
Locking the entire collection is a performance overhead.
This essentially gives access to only one thread to the entire map & blocks all the other threads.
It may cause contention.
SynchronizedHashMap returns Iterator, which fails-fast on concurrent modification.
集合类 |
Key |
Value |
Super |
说明 |
Hashtable |
不允许为 null |
不允许为 null |
Dictionary |
线程安全 |
ConcurrentHashMap |
不允许为 null |
不允许为 null |
AbstractMap |
线程局部安全 |
TreeMap |
不允许为 null |
允许为 null |
AbstractMap |
线程不安全 |
HashMap |
允许为 null |
允许为 null |
AbstractMap |
线程不安全 |
Java Maps的更多相关文章
- Java Maps的9个常见问题
一般来说,Map是一种由键值对组成的数据结构,其中键(key)在Map中是不能重复的: 本篇文章总结了9个最常见的问题(关于Java Map及其实现类): 出于简单考虑,在代码例子中我将不使用泛型,因 ...
- Java开发者常犯的十个错误
翻译自:Top 10 Mistakes Java Developers Make 文章列出了Java开发者最常犯的是个错误. 1.将数组转换为ArrayList 为了将数组转换为ArrayList,开 ...
- Top 10 Mistakes Java Developers Make(转)
文章列出了Java开发者最常犯的是个错误. 1.将数组转换为ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: ? 1 List<String> list = A ...
- Java 学习(21):Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...
- python调用Java方法传入HashMap ArrayList
1.Java代码: package com; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap ...
- jackson官方快速入门文档
官方地址: http://jackson.codehaus.org/ http://wiki.fasterxml.com/JacksonInFiveMinutes http://wiki.faster ...
- Caching Best Practices--reference
reference:http://java.dzone.com/articles/caching-best-practices There is an irresistible attraction ...
- Jackson - Quickstart
JSON Three Ways Jackson offers three alternative methods (one with two variants) for processing JSON ...
- Scala入门指南与建议
最近在学习使用Scala语言做项目,感觉这门语言实在是太优美了!作为一个本科数学.研究生机器学习专业的混合人才(哈哈),这门语言真的是满足了普通计算机编程(告诉计算机怎么做)和函数式编程(告诉计算机做 ...
随机推荐
- scrollWidth,offsetWidth,clientWidth,width;scrollHeight,offsetHeight,clientHeight,height;offsetTop,scrollTop,top;offsetLeft,scrollLeft,left还有谁
题中的那么多属性让人头都大了,他们到底是什么意思?不同浏览器的实现是一样的吗?以下所有结论来自chrome版本 53.0.2785.89 (64-bit)和firefox版本52.0.2,操作系统ub ...
- 对象的创建过程(chapter5.7.3)
总结一下对象的创建过程,假设有一个名为Dog的类: 1. 即使没有显示地使用static关键字,构造器实际上也是静态的方法,因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类 ...
- java基础--动态代理实现与原理详细分析
关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式 ...
- Python爬虫 Cookie的使用
Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的.那么 ...
- 将1、2、3、……、n这n个连续自然数分成g组,使每组的和相等。g组中个数最多的一组有几个?
<style type="text/css"> #content { width: 600px; margin: 150px auto 0 auto; } dl dd ...
- KMP算法【代码】
废话不多说,看毛片算法的核心在于next数组. 很多地方用的都是严书上的方法来求解next数组,代码确实简洁明了,但是可能对于初学者来说不容易想到,甚至不是一下子能理解.(好了,其实我说的就是自己,别 ...
- 关于binary log一点总结[转]
阅读目录(Content) 1 what's binary log 2 Binary Logging Options and Variables 2.1 基础参数 3 Binary Logging F ...
- Html 经典布局(三)
经典布局案例(三): <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 初学grunt压缩
初学grunt 压缩,做个记录.备忘. [JS压缩] 先比较yui compressor 与 uglify 代码压缩, yui compressor,使用起来很简单.需要jdk. https://g ...
- 使用NPOI写入Excel数据(ASP.NET)
第一次做这个写入数据的功能,研究了下npoi的类 IWorkbook wb = new HSSFWorkbook(); //创建表 ISheet sh = wb.CreateSheet("X ...