站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题关于在IBM上看到的一个synchronized问题

关于在IBM上看到的一个synchronized问题

摘要: 关于在IBM上看到的一个synchronized问题


取自:轻松使用线程: 减少争用(来自IBM developerWorks)

清单 3. 一个减小锁的粒度的机会

public class AttributesStore {
private HashMap usersMap = new HashMap();
private HashMap servicesMap = new HashMap();

public synchronized void setUserInfo(String user, UserInfo userInfo) {
usersMap.put(user, userInfo);
}

public synchronized UserInfo getUserInfo(String user) {
return usersMap.get(user);
}

public synchronized void setServiceInfo(String service,
ServiceInfo serviceInfo) {
servicesMap.put(service, serviceInfo);
}

public synchronized ServiceInfo getServiceInfo(String service) {
return servicesMap.get(service);
}
}

这里,用户和服务数据的访问器方法是同步的,这意味着它们在 AttributesStore 对象上同步。虽然这样做是完全线程安全的,但却增加了毫无实际意义的争用可能性。如果一个线程正在执行 setUserInfo ,就不仅意味着其它线程将被锁在 setUserInfo 和 getUserInfo 外面(这是我们希望的),而且意味着它们也将被锁在 getServiceInfo 和 setServiceInfo 外面。


以上来自IBM developerWorks。


如上面所说一个线程正在执行 setUserInfo ,那么其他线程都会被锁在另外三个函数外面,有点不理解,在函数前加synchronized,难道不仅仅锁住该函数吗?


应该是对象同步


刚刚找楼主所说的原文看过了,文章已经很清楚的说明:楼主所举的代码是在AttributesStore的对象上进行同步。
但因为该类中有两个属性,即usersMap与servicesMap,且这两个属性互相独立。这样一来,在整个对象上进行同步,显然是粗粒度的,增加了阻塞机会。如果分别对这两个对象进行线程同步处理,则不会出现“一个线程正在执行 setUserInfo ,那么其他线程都会被锁在另外三个函数外面”。而是“一个线程正在执行setUserInfo,那么其他线程就不能执行getUserInfo。但可以执行另外两个函数”这样可以减少50%机率的阻塞

不知有没有说清楚,楼主可以再将原文看一遍


收到。


如上面所说一个线程正在执行 setUserInfo ,那么其他线程都会被锁在另外三个函数外面,有点不理解,在函数前加synchronized,难道不仅仅锁住该函数吗?


///
当然啊,一个线程正在执行 setUserInfo ,那么其他线程都会被锁在另外三个函数外.
这里的原因主要是同步方法前的synchronized不是"仅仅锁住该函数",而是锁住该函数所属的整个对象,这个对象中的synchronized方法都共享这把锁.

看下面的代码你就明白了.

public synchronized void setUserInfo(String user, UserInfo userInfo) {
usersMap.put(user, userInfo);
}

相当于:

public void setUserInfo(String user, UserInfo userInfo) {
synchronized(this){
usersMap.put(user, userInfo);
}
}

//




明白


再细化一下就可以了


↑返回目录
前一篇: 为什么所有的application都不能马上显示容器里的东西呢?需要拉动窗口一下
后一篇: parseDouble返回的是double,为什么Double的封装器也能接受呀