线程阻塞的问题
关键字:Spring, 单例,同步,线程阻塞,粒度
现象:某大型保险公司的OA应用(大集中模式,用户有2万多人,8千多个组织)在200多用户在线时,竟然发生了weblogic实例挂起,分析dump文件,发现有一个流程提交的线程发生意外,一直占有着一个对象的锁,因此它竟然阻塞了200多个线程,而所有的线程都阻塞在一个叫A的对象上,而这些被阻塞的线程还是处理不同的任务(就是说调用不同的方法),然后马上去看A.java的代码,发现这个类的所有方法都加了synchronized关键字,即都进行了同步,代码示例如下:
public class AImpl{
public void synchronized test1(){
}
public void synchronized test2(){
}
public void synchronized test3(){
}
}
public class BImpl{
private A a;
public void setA(A a){
this.a = a;
}
public void b_test1(){
a.test1();
}
pubic void b_test2(){
a.test2();
}
public void b_test3(){
a.test3();
}
}
问题出来了,有一个线程在执行b_test1()方法,而线程2在执行b_test2()方法,线程3在执行b_test3()方法,结果后面2个线程都被线程1阻塞了,等待它释放持有的a对象的这把锁,为什么会这样呢?而看AImpl.java这个类,其实作者的目的只是希望test1、test2、test3这三个方法在同一个时刻各自只有一个线程执行(即test1在同一个时刻只能有一个线程执行,其它要执行test1的线程只能排队,而test1、test2、test3三个方法是可以并发执行的),但是真实的现象是:test1、test2、test3三个方法都在排对了!也就是说test2、test3两个方法都在等待对象a的锁,而a的锁被执行test1方法的线程所持有了,为什么会这样呢,单例!突然想到了Spring的bean在默认情况下都是单态的,也就是说a对象在整个虚拟机都是唯一的!因此AImpl.java中的所有互不相干的方法都只能串行执行了!oh,my god!
解决办法:
1、 将AImpl.java拆分,也就说把test1、test2、test3三个方法分拆到三个类中去,这样就会有各自的实例,因此不再发生test1、test2、test3三个方法互相排队的事情发生
2、 利用一个小技巧,即我们不动AImpl.java的代码,只是在Spring的xxx.bean.xml的配置文件中,分别为test1、test2、test3三个方法配置三个实例就可以了(即a1,a2,a3),然后修改BImpl.java如下:
public class BImpl{
private A a1;
private A a2;
private A a3;
public void setA1(A a1){
this.a1 = a1;
}
public void setA2(A a2){
this.a2 = a2;
}
public void setA3(A a3){
this.a3 = a3;
}
public void b_test1(){
a1.test1();
}
pubic void b_test2(){
a2.test2();
}
public void b_test3(){
a3.test3();
}
}
总结:解决问题的本质在于一定要明白synchronized关键字锁住的是实例对象,因此问题的发生和解决都是基于它的
分享到:
相关推荐
单态模式单态模式单态模式
单态模式单态模式单态模式
Java实现单态登录
是个使用java实现的单态例子,开始接触java单态的或是不了解单态是怎么实现的同僚,是个不错的参考
Java实现的单态登陆,里面有详细代码注释,也可参展这篇博客看看实现思路:http://blog.csdn.net/hongfeideng/article/details/7023865
这个一个简单的java例子,可以为新手加深对java单态模式的理解.....
Net单态模式的案例 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
MyEclipse\单态.rar
单态登录的源代码
Spring设计思想 Spring实现了两种基本设计模式工厂模式 单态模式
设计模式是在大量的实践中总结和理论化之后优选 的代码结构、编程风格以及解决问题的思考方式。
单态模式的定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 在项目的很多地方都会用到它,比如说数据库的链接。 使用Singleton的好处还在于可以节省内存,因为它限制了实例...
在C#、Java里面常用单态模式,单态模式的好处就不必说了,可提高代码的运行效率....按现有网站上搜索资料写单态模式时,调试总是提示失败,因此自己动手写一个例子供广大mfc入门学习者参考。
单态模式的设计和应用--设计模式之Singleton(单态)
单态模式和工厂模式.ppt单态模式和工厂模式.ppt
有利于学习和掌握单态模式,是我们学习的关键
设计模式之Singleton(单态)
主要介绍了php简单实现单态设计模式的方法,简单分析了单态设计模式的构成、实现与使用方法,需要的朋友可以参考下
单态模式和简单工厂模式.doc
单态模式和简单工厂模式.pdf