`
lshh83
  • 浏览: 162494 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

多线程操作hashtable的问题

 
阅读更多

大家都知道hashmap是线程不安全的,hashtable是线程安全的,如果涉及多线程,推荐用hashtable。

但在一边插入,一边遍历查询的时候,hashtable会报错:

Java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
        at java.util.HashMap$KeyIterator.next(HashMap.java:828)

 代码如下:

package com.luo.service;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class MapTest {

//	public static ConcurrentHashMap cmap = new ConcurrentHashMap();
	public static Hashtable cmap = new Hashtable();
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		MapThreadAdd mt2 = new MapThreadAdd();
		Thread addThread = new Thread(mt2,"");
		addThread.start();
		try{
			Thread.sleep(1);
		}catch(Exception e){
			
		}
		while(true){
			if(cmap.size()>=5){
				Iterator<String> it = cmap.keySet().iterator();
				while(it.hasNext()){
					System.out.println("************************");
					String key = it.next();
//					it.remove();//通过Iterator修改Hashtable
					String value = (String)cmap.get(key);
					System.out.println("循环key:"+key);
				}
			}
		}
	}

}

 

package com.luo.service;

public class MapThreadAdd implements Runnable{
	
	public void run(){
		for(int i=0;i<100;i++){
			MapTest.cmap.put("key"+i, i+"");
			try{
				Thread.sleep(10);
			}catch(Exception e){
				
			}
		}
	}
}

 原因:Iterator做遍历的时候,HashMap被修改(bb.remove(ele), size-1),Iterator(Object ele=it.next())会检查HashMap的size,size发生变化,抛出错误ConcurrentModificationException。

解决办法:

1) 通过Iterator修改Hashtable
while(it.hasNext()) {
Object ele = it.next();
            it.remove();
}

2) 根据实际程序,您自己手动给Iterator遍历的那段程序加锁,给修改HashMap的那段程序加锁。


3) 使用“ConcurrentHashMap”替换HashMap,ConcurrentHashMap会自己检查修改操作,对其加锁,也可针对插入操作。
import java.util.concurrent.*;

分享到:
评论

相关推荐

    关于如何解决HashMap线程安全问题的介绍

    3. 使用HashTable:虽然HashTable是线程安全的,但由于其所有操作都是同步的,所以在多线程并发访问时,性能较低。因此,在现代Java开发中,通常更倾向于使用ConcurrentHashMap。 4. 避免在多线程环境中直接使用...

    HashTable 常用操作

    - **线程安全**:`Hashtable`是线程安全的,可以在多线程环境中安全地使用。但是,如果应用程序只需要单线程访问,那么可以考虑使用`Dictionary, TValue&gt;`,后者在单线程环境下提供了更好的性能。 #### 五、总结 ...

    servlet线程安全问题

    Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性问题。 Servlet 的多线程机制是建立在 Java 多线程机制之上的。Servlet 容器会自动使用线程池等技术来支持...

    Java多线程的总结

    Java集合框架中有一些线程安全的类,如Vector、HashTable、ConcurrentHashMap等,它们内部实现了同步机制,可以在多线程环境中直接使用,避免了手动同步的复杂性。 十、线程局部变量 ThreadLocal为每个线程都创建了...

    hashtable存储数据.rar

    2. **线程安全**:所有对`Hashtable`的操作都是原子性的,因此在多线程环境下无需额外的同步控制。 3. **迭代器的失败安全**:即使在遍历过程中修改了`Hashtable`,也不会抛出`ConcurrentModificationException`,...

    WinFormHashTable最简单用法,.net hashtable ,hashtable ,hashtable用法

    如果在多线程环境中使用,需要手动实现同步机制,如使用`SyncRoot`属性或锁定机制。 - **性能优化**:虽然Hashtable提供快速访问,但如果哈希函数设计不当,可能导致冲突过多,降低性能。应合理选择键的类型和实现...

    hashtable和hashmap的区别

    - **Hashtable**: 由于其线程安全的特性,`Hashtable`在多线程环境中较为安全,但性能较低。全局锁的使用限制了其并发能力。 - **HashMap**: 在单线程环境中性能更佳,因为没有同步开销。在多线程环境中,可以通过...

    Java多线程小结

    ### Java多线程小结 ...但是,多线程编程也面临着诸如死锁、竞态条件等问题,因此需要开发者具备良好的设计思路和扎实的基础知识。掌握多线程的原理和实现机制对于编写高质量的Java应用至关重要。

    hashtable和dictionary的探讨

    相比之下,Dictionary在多线程环境下需要开发者自己处理同步问题,但在单线程或已经进行了同步控制的多线程环境中,Dictionary通常更快。 结构上的差异还体现在异常策略上。Hashtable不允许null键和null值,而...

    浅谈Java web中基于Hashtable的数据库操作.zip

    - **线程安全的代价**:由于Hashtable是线程安全的,它的内部实现使用了synchronized关键字,这可能导致在多线程环境下的性能问题。 - **无泛型支持**:Hashtable属于旧版集合框架,不支持泛型,这意味着在使用时...

    HashMap与HashTable区别

    这意味着在多线程环境中,对`HashTable`的操作不会导致数据不一致的情况发生。 - **HashMap**: 默认是非线程安全的。如果多个线程同时访问一个`HashMap`实例,且至少有一个线程修改了该`HashMap`,则必须通过外部...

    hashmap与hashtable区别

    当单个线程操作`Hashtable`时,其性能不如`HashMap`高效。另一方面,`HashMap`通过提供同步的包装器类,使得开发者可以根据实际需求选择是否启用同步机制,从而在大多数情况下提供更好的性能。 #### 6. 使用场景...

    servlet多线程

    3. **使用同步的集合类**:如`Vector`代替`ArrayList`,`Hashtable`代替`HashMap`,以确保数据结构在多线程环境中的线程安全性。 4. **避免在Servlet中创建额外线程**:由于Servlet本身已具备多线程特性,额外创建...

    C#-Hashtable应用

    此外,Hashtable不是线程安全的,如果你需要在多线程环境中使用,需要额外的同步措施,例如使用lock关键字。或者,可以选择使用ConcurrentDictionary,它是.NET Framework中线程安全的键值对集合。 总结来说,C#的...

    HashTable的java实现

    在Java中,`HashTable`类是最早的同步容器类之一,它是线程安全的,意味着在多线程环境下可以安全地使用。然而,由于其所有的操作都是同步的,这在单线程环境中可能会导致性能下降。`HashTable`不支持空键和空值,且...

    Hashtable的使用

    - **线程安全**:`Hashtable`是线程安全的,这意味着在多线程环境下,它的操作不会引发数据不一致问题。而`HashMap`则不是线程安全的,如果需要在多线程环境下使用,通常需要使用`Collections.synchronizedMap()`来...

    hashMap和hashTable的区别

    - **HashMap**:在 Java 8 中引入了并行化能力,通过 `ConcurrentHashMap` 的实现方式,提高了多线程环境下的性能。 - **HashTable**:由于其同步策略,不适用于高并发场景。 9. **迭代器**: - **HashMap**:...

    深入Java多线程和并发编程

    在这个示例中,`ArrayList`和`HashMap`本身不是线程安全的容器,直接在多线程环境中使用这些容器进行迭代操作时可能会引发数据不一致问题。为了保证线程安全性,可以考虑使用`Collections.synchronizedList`、`...

    浅谈Java web中基于Hashtable的数据库操作.pdf

    Hashtable类是Java Collections Framework的一部分,与HashMap有着密切的关系,但与HashMap不同的是,Hashtable是同步的,因此在多线程环境中更安全,不过这也会带来一些性能开销。 Hashtable的关键特性如下: 1. ...

    多线程与高并发-电子.pdf

    多线程与高并发是计算机科学中非常重要的两个概念,它们在提高软件程序的性能、响应速度和资源利用率方面起着至关重要的作用。在当今的互联网时代,特别是在产业互联网和5G技术的推动下,多线程和高并发的应用变得...

Global site tag (gtag.js) - Google Analytics