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());
}
}
Are final
fields inherently thread-safe? In the above code the map
variable is marked as final
, does that mean that it is thread-safe?
If the variable is not thread-safe I expect that the output from the main
-method should be a "2" but I am getting either "1" or "0"
EDIT
If I declare the variable using the volatile
keyword, i.e.
volatile HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
the map
variable is seemingly not thread-safe, why is this? However the below method seems to work, why is this?
public synchronized void putValue(int key,int value){
if(map.isEmpty()){
System.out.println("hello");
map.put(key,value);
}
Will using Collections.unmodifiableMap(map)
work?