天天看点

ConcurrentModificationException

项目中有一处多线程访问HashTable的地方;一个线程对 HashTable进行遍历,一个线程对它进行增、删操作。项目运行一段时间之后,就时不时的报一个java.util.ConcurrentModificationException 出来,然后线程死翘翘了。

上网查了一下,这个异常的原因是在对HashTable进行遍历时,对HashTable进行了增、删操作。如果是单线程的操作,应该 把增、删操作拿到HastTable外面来;如果是多线程的操作,似乎就要使用多线程同步机制了。

但是,并没有这么复杂。我写了一个测试类,分别测试了两种遍历和增删HashTable的方法。代码如下:

package test;

import java.util.Enumeration;

import java.util.Hashtable;

import java.util.Iterator;

import org.junit.Before;

import org.junit.Test;

public class HasttableTest {

 private Hashtable<String, String> table;

 private int i;

 @Before

 public void setUp() throws Exception {

  i = 0;

  table = new Hashtable<String, String>();

  table.put("a", "aa");

  table.put("b", "bb");

  table.put("c", "cc");

 }

 @Test

 public void testEnu() {

  System.out.println("Enumeration 遍历开始");

  Enumeration<String> keys = table.keys();

  while (keys.hasMoreElements()) {

   i++;

   String key = (String) keys.nextElement();

   System.out.println(key + "---" + table.get(key));

   System.out.println("i=" + i);

   if (i == 1) {

    table.put("d", "dd");

    table.remove("b");

   }

  }

  System.out.println("Enumeration 遍历结束");

 public void TestIte() {

  System.out.println("Iterator遍 历开始");

  Iterator<String> it = table.keySet().iterator();

  while (it.hasNext()) {

   String key = (String) it.next();

    // table.put("d", "dd");

    table.remove("c");

  System.out.println("Iterator 遍历结束");

}

执行的结果是,testEnu()方法能够正常执行完毕,而TestIte()方法则会跑出异常。

为什么会这样?我上网查了一下,准确的答案忘记了,大体上是说,HashTable、Enumeration等是线程安全的,在多线程操作中会自己 进行同步;而Iterator等则是不安全的,如果使用它,就要由程序显式的进行同步操作。

本文转自 斯然在天边 51CTO博客,原文链接:http://blog.51cto.com/winters1224/798950,如需转载请自行联系原作者

继续阅读