这个ConcurrentHashMap在初始化数据时创建,读表添加了数据,然后我想在下一次热更这个对象的数据,我用了一个clear操作,但是如何在ConcurrentHashMap.clear()的时候,其他线程读取不了ConcurrentHashMap里面的空数据,处于阻塞状态。直接加synchronized(ConcurrentHashMap){}好像达不到效果,别的线程想通过get()方法获取内容照样能获取到,想synchronized(""){ConcurrentHashMap.clear();再进行ConcurrentHashMap.put()操作},好像也不行,因为其他线程不是并发访问热更这个方法,而是访问静态对象ConcurrentHashMap,求解
封装一层clear,在clear中lock;
封装读取也是用该锁;
牛逼牛逼,我好像懂了。但是读取也是用该锁怎么操作,我现在clear之后要for循环重新读数据放入map中,所以应该是clear操作和put操作属于一个原子操作才行,但是put操作是需要for循环读List<Object>的,就要传入List<Object>这个对象,对象如果设计成泛型,要用反射获取类方法,是这样吗。反射这块代码不是很会写,我网上搜搜,或则你说的这个使用同一个锁怎么写,能不能给个样板^_^
class MyConcurrentHashMap<K,T> extends ConcurrentHashMap<K,T>{
private static final long serialVersionUID = 1L;
Lock lock = new ReentrantLock();
/** (non-Javadoc)
* @see java.util.concurrent.ConcurrentHashMap#get(java.lang.Object)
*/
@Override
public T get(Object paramObject) {
lock.lock();
try{
return super.get(paramObject);
}finally{
lock.unlock();
}
}
@SuppressWarnings("unchecked")
public <E> void clearAndPut(List<E> list) {
lock.lock();
try{
super.clear();
for(int i=0; i<list.size(); i++){
E e = list.get(i);
Class<?> cla = e.getClass();
Field declaredField = e.getClass().getDeclaredField("lv");
Constructor<?> constructor = cla.getConstructor(Integer.class,String.class);
Field f = e.getClass().getDeclaredField("lv");
Field f2 = e.getClass().getDeclaredField("str");
f.setAccessible(true);f2.setAccessible(true);
e.getClass().getDeclaredField("str").setAccessible(true);
Object obj = constructor.newInstance(f.get(e),f2.get(e));
Method getLv = cla.getMethod("getLv");
Method getStr = cla.getMethod("getStr");
K lv = (K)getLv.invoke(obj);
T str = (T)getStr.invoke(obj);
super.put(lv, str);
}
Thread.currentThread().sleep(10000);
System.out.println("clear操作.....................................");
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
};
}
根据楼上老哥自己重写了ConcurrentHashMap,大概就是这个样子,测试了没问题,在执行clearAndPut操作的时候,sleep10秒,这10秒钟,给get加了锁的话,get是会处于等待状态的。今天来结一下贴