歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java Hashtable多線程操作遍歷問題

最近發現程序經常報出java.util.ConcurrentModificationException異常.發現其一個互斥作用的hashtable線程周期性去除無用key報錯,導致hashtable值不斷增大.

檢測線程為單獨線程,每一小時檢測一次,使用java的iterator進行遍歷.問題就出在iterator.在使用iterator遍歷時不能使用原hashtable的put與remove方法,要不就會報java.util.ConcurrentModificationException異常,上鎖的話可能會造成性能問題.

經過測試優化的處理方式為改為

   Enumeration<String> e1 = T1.map.keys();
   while (e1.hasMoreElements()) {
    String key = e1.nextElement();
    String ret = T1.map.remove(key);
   }

以後還是少用iterator為妙.

以下為測試程序,有興趣可以跑跑

public class T1 extends Thread{
 public static Hashtable<String, String> map = new Hashtable<String, String>();
 
 
 public void run() {
  super.run();
  while(true)
  {
   for (int i = 0; i < 100; i++) {
    map.put(String.valueOf(System.currentTimeMillis())+i, "");
   }
   System.out.println("add 100---->"+map.size());
   Random rd = new Random();
   try {
    Thread.sleep(rd.nextInt(10));
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 
 public static void main(String[] args) throws InterruptedException {
  T1 t1 = new T1();
  t1.start();
  T2 t2 = new T2();
  t2.start();
 }
}

 

public class T2 extends Thread{
 
 
 
 public void run() {
  super.run();
  while(true)
  {
   System.out.println("map----size 01:"+T1.map.size());
//   異常的邏輯
//   Iterator it = T1.map.entrySet().iterator();
//   while (it.hasNext()) {
//    it.next();
//    it.remove();
//   }
   
   Enumeration<String> e1 = T1.map.keys();
   while (e1.hasMoreElements()) {
    String key = e1.nextElement();
    String ret = T1.map.remove(key);
   }
   
   System.out.println("map----size 02:"+T1.map.size());
   
   Random rd = new Random();
   try {
    Thread.sleep(rd.nextInt(10));
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
}

如果有其它更好的方法或意見可以聯系我.大家一起討論一下。

Copyright © Linux教程網 All Rights Reserved