Bau*_*han 5 java multithreading concurrenthashmap
我在某处读到,即使ConcurrentHashMap保证在多个线程中使用它也是安全的,它应该被声明为final,甚至private final.我的问题如下:
1)CocurrentHashMap如果不将其声明为仍然保持线程安全final吗?
2)关于私人关键字的相同问题.可能最好问一般问题 - public/private关键字会影响运行时行为吗?我理解它们在内部/外部类的可见性/用法方面的含义,但在多线程运行时的上下文中意味着什么呢?我认为代码public ConcurrentHashMap可能只是在编码风格术语中不正确而不是在运行时,我是对的吗?
在评论中提供我所谈论的内容的更具体的例子可能会有所帮助.让我们说我做这样的事情:
public class CHMHolder {
private /*non-final*/ CHMHolder instance;
public static CHMHolder getInstance() {
if (instance == null) {
instance = new CHMHolder();
}
return instance;
}
private ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
public ConcurrentHashMap<String, String> getMap() {
return map;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,由于一大堆原因,这不是线程安全的!但是,让我们说threadA看到一个null值instance并因此实例化CHMHolder,然后通过一个愉快的巧合,然后threadB看到相同的CHMHolder实例(由于没有同步,因此无法保证).你会认为threadB看到非null CHMHolder.map,对吗?它可能没有,因为在threadA map = new ...和threadB 之间没有正式的发生边缘return map.
这在实践中意味着什么样的东西CHMHolder.getInstance().getMap().isEmpty()可以扔掉NullPointerException,这会让人感到困惑 - 毕竟,getInstance看起来应该总是返回一个非null CHMHolder,CHMHolder看起来应该总是有一个非null地图.啊,多线程的乐趣!
如果map已标记final,那么user2864740引用的JLS位适用.这意味着如果threadB看到threadA看到的同一个实例(也可能不是),那么它也会看到所做的map = new...操作threadA- 也就是说,它会看到非nullCHM实例.一旦看到,CHM的内部线程安全就足以确保安全访问.
| 归档时间: |
|
| 查看次数: |
873 次 |
| 最近记录: |