首页 新闻 会员 周边

怎么使在并发访问ConcurrentHashMap对象的时候的时候,阻塞线程

0
悬赏园豆:10 [已解决问题] 解决于 2019-01-22 11:02

这个ConcurrentHashMap在初始化数据时创建,读表添加了数据,然后我想在下一次热更这个对象的数据,我用了一个clear操作,但是如何在ConcurrentHashMap.clear()的时候,其他线程读取不了ConcurrentHashMap里面的空数据,处于阻塞状态。直接加synchronized(ConcurrentHashMap){}好像达不到效果,别的线程想通过get()方法获取内容照样能获取到,想synchronized(""){ConcurrentHashMap.clear();再进行ConcurrentHashMap.put()操作},好像也不行,因为其他线程不是并发访问热更这个方法,而是访问静态对象ConcurrentHashMap,求解

YAN_HUAXIANGMO的主页 YAN_HUAXIANGMO | 初学一级 | 园豆:189
提问于:2019-01-18 10:20
< >
分享
最佳答案
0

封装一层clear,在clear中lock;
封装读取也是用该锁;

收获园豆:10
花飘水流兮 | 专家六级 |园豆:13560 | 2019-01-18 11:39

牛逼牛逼,我好像懂了。但是读取也是用该锁怎么操作,我现在clear之后要for循环重新读数据放入map中,所以应该是clear操作和put操作属于一个原子操作才行,但是put操作是需要for循环读List<Object>的,就要传入List<Object>这个对象,对象如果设计成泛型,要用反射获取类方法,是这样吗。反射这块代码不是很会写,我网上搜搜,或则你说的这个使用同一个锁怎么写,能不能给个样板^_^

YAN_HUAXIANGMO | 园豆:189 (初学一级) | 2019-01-18 16:08
其他回答(1)
0

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是会处于等待状态的。今天来结一下贴

YAN_HUAXIANGMO | 园豆:189 (初学一级) | 2019-01-22 11:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册