`
lshh83
  • 浏览: 159670 次
  • 性别: 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.*;

分享到:
评论

相关推荐

    Hashtable和HashMap的区别:

    Hashtable和HashMap的区别: ...即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:

    Java并发编程相关源码集 包括多任务线程,线程池等.rar

     volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...

    Java集合框架完整说明便于了解集合

    HashMap 和 Hashtable 的区别,HashSet如何检查重复,HashMap的底层实现,HashMap 多线程操作导致死循环问题,ConcurrentHashMap 和 Hashtable 的区别,ConcurrentHashMap线程安全的具体实现⽅式/底层具体实现,...

    火车采集器采集原理,流程介绍

    3、使用了SQLite数据库连接池,保证在多线程下Sqlite的稳定操作。 4、修正了在多任务同时更新时,同任务不断增加,导致界面上任务数越来越多的问题。 5、状态栏小提示同完成提示音一起,可以关闭显示。 6、去掉了...

    ArrayList.md

    2. 多个线程同时进行put、remove等操作时并不会阻塞,可以同时进行,和HashTable不同,HashTable在操作时,会锁住整个Map; 3. 迭代过程中,即使Map结构被修改,也不会抛ConcurrentModificationException异常; 4. ...

    Java并发编程笔记之ConcurrentHashMap原理探究.docx

    HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占,相当于所有线程进行读写时都去竞争一把锁,导致效率非常低下。ConcurrentHashMap可以做到读取数据不...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【多线程】多线程的实现方式Thread、Runnable、Callable 72 【多线程】实现Runnable接口与继承Thread类比较 73 【多线程】线程状态转换 74 【多线程】线程的调度 75 线程优先级 75 sleep 76 wait 76 yield 77 join ...

    java面试笔试资料包括JAVA基础核心知识点深度学习Spring面试题等资料合集.zip

    JAVA多线程之线程间的通信方式.docx Java注解详解.docx Java线程池.docx JDK1.8Stream操作.docx JDK8有新特性.docx JVM堆三代.docx JVM的垃圾回收机制详解和调优.docx Spring源码分析之IoC.docx 关于线程和线程池的...

    JAVA面试题最全集

    多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端与服务器的通信的过程 60.JAVA语言国际化应用,Locale类,Unicode 61.描述反射机制的作用 62.如何读写一个...

    30重点面试题-Fu1

    1.同步特性不同 HashMap 同一时间允许多个线程同时进行操作 效率较高 但是可能出现并发错误 Hashtable 同一时间只允许一个线程进行操作 效率较低

    java面试题.docx

    企业常见java面试题,java基础,java进阶 JDK 和 JRE 有什么区别? == 和 equals 的区别是什么? 两个对象的 hashCode()相同,则 equals()也一定为 true,... 在 java 程序中怎么保证多线程的运行安全? 什么是死锁?

    大数据面试题.pdf

    如果是对其它指定位置的插⼊、删除操作,最好选择 LinkedList HashMap、HashTable 的区别及其优缺点: HashTable 中的⽅法是同步的 HashMap 的⽅法在缺省情况下是⾮同步的 因此在多线程环境下需要做额外的同步机制。...

    关于JAVA面试的100题及其答案

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    Java并发编程(学习笔记).xmind

    (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程...

    进销存系统文档作业例子

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    .net性能优化宝典

    1.3 多线程... 6 1.3.1 线程同步... 6 1.3.2 使用 ThreadStatic 替代 NameDataSlot ★... 7 1.3.3 多线程编程技巧... 7 1.4 类型系统... 8 1.4.1 避免无意义的变量初始化动作... 8 1.4.2 ValueType 和 ...

    Java的六大问题你都懂了吗

    在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它"永远不变".其实那是...

    张孝祥Java就业培训教程.pdf

    在以后的章节中,用通俗易懂的手法,紧密联系实际应用的方式,深入浅出地讲解了多线程,常用Java类,Java中的I/O(输入输出)编程,GUI与Applet,网络编程等方面的知识。 本书许多内容都来源于程序员圈子里的非正式...

    Java初学者都必须理解的六大问题

    不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,...

Global site tag (gtag.js) - Google Analytics