取自:轻松使用线程: 减少争用(来自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,难道不仅仅锁住该函数吗?
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,难道不仅仅锁住该函数吗?
解决方案 »
- 大家帮忙看下,为什么会编译错误?
- 域网网文件传输,急!!!
- 如何用java得到文件的owner?在线等,急急!!!!谢谢!!(当时给分)
- 麻烦大家看看这个错误(```有点郁闷)
- 求救, 急啊, 请问如何设置在弹出一个Frame时把它设置成Modal形式, 谢谢!!!
- 文本加密后传输问题要从byte转成char,为什么?
- JSP?急!在线等待!
- 菜鸟问题,高手莫入!
- jbuider 中dbSwing的FontChooser在哪里?
- 在JAVA数据库编程中,怎么对两个不同类型的数据库同时操作?
- 【请问】市面上有什么好书是来介绍在linux下面开发java程序的吗
- 请问JAVA如何实现登陆WEB网站?给个具体得例子可以好吗?
但因为该类中有两个属性,即usersMap与servicesMap,且这两个属性互相独立。这样一来,在整个对象上进行同步,显然是粗粒度的,增加了阻塞机会。如果分别对这两个对象进行线程同步处理,则不会出现“一个线程正在执行 setUserInfo ,那么其他线程都会被锁在另外三个函数外面”。而是“一个线程正在执行setUserInfo,那么其他线程就不能执行getUserInfo。但可以执行另外两个函数”这样可以减少50%机率的阻塞不知有没有说清楚,楼主可以再将原文看一遍
///
当然啊,一个线程正在执行 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);
}
}//
帮你顶了!!