java.util.ConcurrentModificationException

应用场景:
n个线程接受MQ信息(其他也一样),然后缓存到一个集合里面,消息有一个key,半小时内这个key的消息有若干,只要时间戳最大一条。
每半小时保存到数据库一次,并清除这个集合,因为高并发,接到消息直接保存,然后再删掉老数据的可行性不大。


本来以为hashtable是线程安全的,但是发现put是没有问题,但是Iterator遍历保存的时候,元素被修改了,线程是不安全的,其中元素被覆盖了,曝出了ConcurrentModificationException异常,如果仅仅是删除,Iterator提供了remove方法,倒好处理。
Iterator的next方法里面会调用 checkForComodification()判断集合是否被修改过,如果修改过就抛出ConcurrentModificationException异常
只有Hashtable本身的方法才是线程安全的,Iterator中的remove已经不是Hashtable中的方法了


1,一个解决方案是hashtable使用clone,拉出来再清空,然后针对clone出来的做遍历,这样完成了我的要求。


2,是使用ConcurrentHashMap,这是一个专门处理高并发的,不保证数据一致性,每个线程拥有自己的Iterator,这样就避免了冲突。

ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,
如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。
ConcurrentHashMap的效率也很高。。。。。


3,Map map =Collections.synchronizedMap(new HashMap());  是不是可以可以保证数据一致?这个没试过。



4,LinkedBlockingQueue,ThreadPoolExecutor、好像好高深的样子,不过好像和我需求不符合,
他是如果数据多,就不断添加队列,一个队列满了就一次性执行掉。。。。。。






下面网页对原因有分析,mark一下
http://www.cnblogs.com/frankliiu-java/articles/1759460.html
http://bbs.csdn.net/topics/390139942
http://blog.csdn.net/xuweilinjijis/article/details/8651167
http://blog.csdn.net/ichsonx/article/details/5337511
http://www.iteye.com/topic/344876


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值