ConcurrentHashMap使用问题 线程安全 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不能。比如你判断了a!=null;正准备执行else的语句。很不巧另外一个线程对你的map进行的操作,导致你的a现在等于null,之前的线程继续执行else语句,这个时候a=null就会抛出空指针异常。一般比较常用的方法是用synchronized关键字 这肯定不行了,虽然ConcurrentHashMap是线程安全的,但是像你这样写,就不是了,你应该用synchronized块,把那段判断语句包围起来! 没有对a==null的操作,只有map.remove(),remove之后对a操作不会空指针吧,但即使这样确实存在数据不一致的问题,A对象内部已经实现了线程安全,主要考虑map增删和业务强相关,要保持线程安全就要加全局锁,但是性能又成问题是不是要考虑数据不一致出现的概率和成本,和加全局锁的性能代价,两难的选择除了synchronized外,还有没有其他方法可以减小颗粒度? private final static ConcurrentMap<String, Future<Object>> cached = new ConcurrentHashMap<String, Future<Object>>(); public Object get(String key) { Future<Object> future = cached.get(key); if (future == null) { Future<Object> newFutrue = new FutureTask<Object>( new Callable<Object>() { @Override public Object call() throws Exception { Object object = null; //TODO 真正的获取value return object; } }); // put if absent 防止缓存穿透。防止同一个Key,多个线程没命中的情况下,穿透至缓存。 future = cached.putIfAbsent(key, newFutrue); if (future == null) { future = newFutrue; } ((FutureTask<Object>) future).run(); } Object value = null; try { value = future.get(30, TimeUnit.SECONDS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); } return value; }本地缓存,请用Future 解决两个问题,1 不用同步 2 解决缓存穿透,防止同一个KEY 没命中之后,同时访问后端。 正确的用法是:V v = map.get(k);if (v == null) { V _v = new V(); v = map.putIfAbsent(k, _v); if (v == null) {v = _v;}}这段代码可以在线程中执行,得到正确的 v。 请教关于 简单工厂的问题 ??请java神解答!!!! 问一个简单的算法问题 请教:jvisualvm启动提示“不能检测到Java应用” JTEST检查时出现的错误 使用插件! 谁能给我说说JToolBar的用法! 谁还有更简单的方法请联系我 求助JSP环境. 文件路径问题 帮忙看诊断一下遇到的问题。 ftp问题请各路大神大发神通解救在下,拜谢~~~~~标题长~~~~~~~~~~~~~~~~~~~已放上全部身家 Swing Jtble 排序后,出现数据刷新问题
比如你判断了a!=null;正准备执行else的语句。很不巧另外一个线程对你的map进行的操作,导致你的a现在等于null
,之前的线程继续执行else语句,这个时候a=null就会抛出空指针异常。一般比较常用的方法是用synchronized关键字
但即使这样确实存在数据不一致的问题,
A对象内部已经实现了线程安全,主要考虑map增删和业务强相关,要保持线程安全就要加全局锁,但是性能又成问题
是不是要考虑数据不一致出现的概率和成本,和加全局锁的性能代价,两难的选择
除了synchronized外,还有没有其他方法可以减小颗粒度?
public Object get(String key) {
Future<Object> future = cached.get(key);
if (future == null) {
Future<Object> newFutrue = new FutureTask<Object>(
new Callable<Object>() {
@Override
public Object call() throws Exception {
Object object = null;
//TODO 真正的获取value
return object;
}
});
// put if absent 防止缓存穿透。防止同一个Key,多个线程没命中的情况下,穿透至缓存。
future = cached.putIfAbsent(key, newFutrue);
if (future == null) {
future = newFutrue;
}
((FutureTask<Object>) future).run();
} Object value = null;
try {
value = future.get(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return value;
}本地缓存,请用Future 解决两个问题,
1 不用同步 2 解决缓存穿透,防止同一个KEY 没命中之后,同时访问后端。
V v = map.get(k);
if (v == null) {
V _v = new V();
v = map.putIfAbsent(k, _v);
if (v == null) {v = _v;}
}
这段代码可以在线程中执行,得到正确的 v。