现有如下代码,为什么getStatsMap1这个不能锁住,而getStatsMap2是可以的,这2者有什么区别,高手帮解释下,谢谢。
依据我的理解,对一个static 变量加锁和对方法加锁应该是效果一样
class TestThread {
private static Map<String, String> statsMap = null;
public Map<String, String> getStatsMap1() {
synchronized (statsMap) {
if (statsMap == null) {
statsMap = getAllTable();
}
}
return statsMap;
}
public synchronized Map<String, String> getStatsMap2() {
if (statsMap == null) {
statsMap = getAllTable();
}
return statsMap;
}
private Map<String, String> getAllTable() {
Map<String, String> map = new HashMap<String, String>();
map.put("user", "user");
return map;
}
}
两个方法锁定的资源不一样。在方法上同步,相当于实例的加锁。
getStatsMap2的代码相当于:
[code="java"]
public Map getStatsMap2() {
synchronized(this){
if (statsMap == null) {
statsMap = getAllTable();
}
return statsMap;
}
}
[/code]
方法1在竞争 statsMap 时会被锁上。但是:statsMap 的初始值为null,代码执行会报错的。
在静态方法上加锁,那么锁的就是类,也就是TestThread.class。
在实例方法上加锁,那么锁的就是对象,也就是TestThread的一个实例。
因为锁的不一样,一个是类,一个是对象,所以这两个方法之间是没有竞争关系的。
你这里是要在静态方法和实例方法中都要去操作一个静态变量statsMap,那么就应该在statsMap上加锁,也就是:synchronized (statsMap) {...},否则就根本达不到效果了。