Java的Hashtable在遍历时的迭代器线程问题

这篇文章主要讲什么 事情的起因

工作中需要在某个业务类中设置一个将一些对象缓存在内存中的一个缓存机制(单机)。于是有了以下类似结构的实现:

1 package org.cnblog.test; 2 3 import java.util.Hashtable; 4 import java.util.Iterator; 5 6 /** 7 * JAVA的Hashtable在遍历时的迭代器线程问题 8 * @author HY 9 */ 10 public class HashtableIteratorTest { 11 12 //初始化缓存,并启动刷新缓存的事件。 13 static { 14 Cache.cacheMap = new Hashtable<String, Long>(); 15 new Cache().start(); 16 } 17 18 /** 19 * 执行Main方法 20 * @param args 21 */ 22 public static void main(String[] args) { 23 24 Thread t = new Thread(new Runnable() { 25 public void run() { 26 while (true) { 27 long time = System.currentTimeMillis(); 28 Cache.cacheMap.put(time + "", time); 29 System.out.println("[" + Thread.currentThread().getName() + "]Cache中新增缓存>>" + time); 30 try { 31 // 每秒钟增加一个缓存实例。 32 Thread.sleep(1*1000); 33 } catch (InterruptedException e) { 34 e.printStackTrace(); 35 } 36 } 37 } 38 }); 39 t.start(); 40 } 41 42 private static class Cache extends Thread { 43 private static Hashtable<String, Long> cacheMap; 44 45 /** 46 * 刷新缓存的方法,清除时间超过10秒的缓存。 47 */ 48 private void refresh() { 49 synchronized (cacheMap) { 50 String key; 51 Iterator<String> i = cacheMap.keySet().iterator(); 52 while (i.hasNext()) { 53 key = i.next(); 54 if (cacheMap.get(key) != null && System.currentTimeMillis() - cacheMap.get(key) > 10*1000) { 55 cacheMap.remove(key); 56 System.out.println("[" + Thread.currentThread().getName() + "]删除的Key值<<" + key); 57 } 58 } 59 } 60 } 61 62 public void run() { 63 while (true) { 64 refresh(); 65 try { 66 // 每过10秒钟作一次缓存刷新 67 Thread.sleep(10*1000); 68 } catch (InterruptedException e) { 69 e.printStackTrace(); 70 } 71 } 72 } 73 } 74 }

业务类HashtableIteratorTest中,使用静态内部类Cache来存储缓存,缓存的直接载体为内部类中的静态成员cacheMap。

内部类Cache为线程类,线程的执行内容为每10秒钟进行一次缓存刷新。(刷新结果是清除掉缓存时间超过10秒的内容)

业务类HashtableIteratorTest在初始化时,启动内部类的线程,并实现一些存入缓存和读取缓存的方法。

代码中的main方法模拟每秒钟增加一个缓存。

于是,代码遇到了以下问题:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f3e409710fddc43675099de40d87eca3.html