• 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();
       }
      }
     }
    }
    如果有其它更好的方法或意见可以联系我.大家一起讨论一下。


     

  • 相关阅读:
    GPU编程和流式多处理器(七)
    GPU编程和流式多处理器(六)
    vue——使用vant轮播组件swipe + flex时,文字抖动问题
    golang 修改字符串
    Go 彻底弄懂return和defer的微妙关系
    Redis 的持久化机制
    Redis 缓存击穿
    Redis 缓存穿透
    Redis 雪崩
    正则验证
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13317868.html
Copyright © 2020-2023  润新知