【发布时间】:2016-12-27 09:35:39
【问题描述】:
public class MapDem {
final HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
public HashMap<Integer,Integer> getMap(){
return map;
}
public void putValue(int key,int value){
map.put(key,value);
}
public static void main(String args[]){
MapDem demo = new MapDem();
new Thread(new Runnable(){
@Override
public void run() {
demo.putValue(1, 10);
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
demo.putValue(1, 10);
}
}).start();
System.out.println(demo.getMap().size());
}
}
final 字段本身是线程安全的吗?在上面的代码中map变量被标记为final,这是否意味着它是线程安全的?
如果变量不是线程安全的,我希望main-方法的输出应该是“2”,但我得到的是“1”或“0”
编辑
如果我使用 volatile 关键字声明变量,即
volatile HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
map 变量似乎不是线程安全的,这是为什么呢?但是下面的方法似乎有效,这是为什么呢?
public synchronized void putValue(int key,int value){
if(map.isEmpty()){
System.out.println("hello");
map.put(key,value);
}
使用Collections.unmodifiableMap(map) 会起作用吗?
【问题讨论】:
-
我不认为您的代码是线程安全的,因为您创建的两个线程可以同时交错和修改映射。
-
我已经浏览了链接,但我不清楚这就是我发布问题的原因。
标签: java multithreading synchronization thread-safety final