在javadoc中找到这样一段话:
代码
- * <p>The iterators returned by all of this class's "collection view methods"
- * are <i>fail-fast</i>: if the map is structurally modified at any time after
- * the iterator is created, in any way except through the iterator's own
- * <tt>remove</tt> or <tt>add</tt> methods, the iterator will throw a
- * <tt>ConcurrentModificationException</tt>. Thus, in the face of concurrent
- * modification, the iterator fails quickly and cleanly, rather than risking
- * arbitrary, non-deterministic behavior at an undetermined time in the
- * future.
<script>render_code();</script>
如果hashmap在迭代的同时,被其他线程修改,则会抛出一个ConcurrentModificationException异常,如以下这段程序:
代码
- package hashmap;
-
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
- import java.util.Map.Entry;
-
- public class HashMapTest {
- private static final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
-
- public static void main(String[] args) {
- try {
- for (int i = 0; i < 10; i++) {
- map.put(i, i);
- }
- new Thread() {
- @Override
- public void run() {
- Set<Entry<Integer, Integer>> set = map.entrySet();
- synchronized (map) {
- Iterator<Entry<Integer, Integer>> it = set.iterator();
- while (it.hasNext()) {
- Entry<Integer, Integer> en = it.next();
- System.out.println(en.getKey());
- }
- }
- }
- }.start();
- for (int i = 0; i < 10; i++) {
- map.put(i, i);
- }
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
- }
- }
<script>render_code();</script>
为了解决这个问题,jdk5.0以前的版本提供了Collections.SynchronizedXX();方法,对已有容器进行同步实现,这样容器在迭代时其他线程就不能同时进行修改了,但是由于Collections.SynchronizedXX()生成的容器把所有方法都进行了同步,其他线程如果只是读取数据也必须等待迭代结束。于是JDK5.0中新加了ConcurrentHashMap类,这个类通过内部独立锁的机制对写操作和读操作分别进行了同步,当一个线程在进行迭代操作时,其他线程也可以同步的读写,Iterator返回的只是某一时点上的,不会抛ConcurrentModificationException异常,比起hashmap效率也不会有太大损失
参考资料:Java 理论与实践: 构建一个更好的 HashMap
Java Map 集合类简介
分享到:
相关推荐
4. **线程安全**:HashMap本身不是线程安全的,如果在多线程环境下使用,需要使用Collections.synchronizedMap()方法或者ConcurrentHashMap。线程安全问题可能导致数据不一致或者死循环等问题。 5. **null键和值**...
1. 使用Collections.synchronizedMap():Java提供了一个便捷的方法,通过Collections.synchronizedMap()可以将HashMap转换为线程安全的Map。但是需要注意,虽然这个方法可以保证基本的线程安全,但迭代仍然是非线程...
如果我么需要有一个线程安全的HashMap,可以使用Collections.synchronizedMap(Map m)方法获得线程安全的HashMap,也可以使用ConcurrentHashMap类创建线程安全的map。 存储的元素在jdk1.7当中是Entry作为存储的
因此,如果需要在并发环境中使用,必须使用同步机制,如`synchronized`关键字或`Collections.synchronizedMap()`方法来保证线程安全。 接着,我们来看`ConcurrentHashMap`,它是Java提供的线程安全的散列映射容器,...
`Collections.synchronizedMap()`方法可以将一个普通`HashMap`转换为线程安全的版本。 **示例**: ```java Map, String> map = Collections.synchronizedMap(new HashMap()); ``` **优点**: - 简单易用。 - 性能...
为了解决这一问题,开发者可以使用`Collections.synchronizedMap()`方法对HashMap进行包装,或者直接使用线程安全的`java.util.concurrent.ConcurrentHashMap`类。 **HashMap的性能优化** HashMap的性能优化主要...
而如果需要线程安全的HashMap,则可以通过Collections的synchronizedMap方法或者使用ConcurrentHashMap来实现。 HashMap的存储结构基于数组+链表+红黑树的方式实现。在JDK 1.8之前,HashMap仅使用数组和链表结构,...
2. **使用`ConcurrentHashMap`**:相比`Collections.synchronizedMap`,`ConcurrentHashMap`提供了更细粒度的锁机制,允许并发读取而不加锁,只在写入时进行加锁,因此性能更高。 #### Collections.synchronizedMap...
1. **非同步**:`HashMap`不是线程安全的,因此在多线程环境下不建议直接使用,可以考虑使用`Collections.synchronizedMap()`方法将其包装为同步的,或者使用`ConcurrentHashMap`。 2. **无序性**:`HashMap`中的...
这些是基于非线程安全的集合(如ArrayList、HashMap)通过`Collections.synchronized*`方法转换得到的。例如,`Collections.synchronizedList`和`Collections.synchronizedMap`。同步集合在每个方法上加锁,确保...
而Collections.synchronizedMap则简单地为HashMap加上了同步控制,当多个线程访问时,会通过锁实现串行化,虽然确保了线程安全,但牺牲了并行性能。 对比这两种机制,ConcurrentHashMap在高并发环境下通常表现更优...
HashMap 不是线程安全的,如果需要在多线程环境中使用,应考虑使用 Collections.synchronizedMap 或其他同步机制。 在选择 Map 实现时,应根据具体的需求来决定,如是否需要线程安全性、是否涉及到枚举类型、性能...
【描述】提到的"ConcurrentHashMap共18页.pdf.zip"表明文档的篇幅适中,可能涵盖`ConcurrentHashMap`的基础概念、关键特性、性能优势以及与其它并发容器(如`synchronized HashMap`和`Collections.synchronizedMap`...
`Hashtable`不允许null键和null值,并且它的实现方式相对过时,现在通常推荐使用`Collections.synchronizedMap()`将`HashMap`转换为线程安全的版本,或者使用`ConcurrentHashMap`,后者在多线程环境下的性能更好。...
- HashMap 未实现同步,这意味着在并发环境中使用需要手动使用 `Collections.synchronizedMap()` 来同步,或者使用 Java 5 引入的 ConcurrentHashMap,它提供了更好的并发性能和扩展性。 - Hashtable 的同步是内置...
- 注意HashMap的并发问题,如果在多线程环境下,使用Collections.synchronizedMap()或使用ConcurrentHashMap来保证线程安全。 总结起来,HashMap和HashSet是Java集合框架的重要组成部分,它们利用哈希技术提供了...
3. **线程安全性**:HashMap不是线程安全的,如果在多线程环境下使用,需要使用Collections.synchronizedMap()进行同步或者使用ConcurrentHashMap,后者是专门为并发设计的哈希映射表。 HashMap类的常见方法包括: ...
为了保证线程安全,可以使用`ConcurrentHashMap`或通过`Collections.synchronizedMap(hashMap)`将HashMap转换为线程同步的Map。 5. 获取方式:只能通过键来获取对应的值,HashMap不支持通过索引来访问元素,这与...
传统的线程安全解决方案,如Hashtable或使用Collections.synchronizedMap包装HashMap,虽然实现了线程安全,但性能上并不理想,因为它们采用了独占锁,只允许单个线程执行操作。 在JDK 1.6版本中,...