由於Spring的單態引起的執行緒阻塞的問題
執行緒阻塞的問題
關鍵字: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關鍵字鎖住的是例項物件,因此問題的發生和解決都是基於它的
相關文章
- 多執行緒引起的效能問題分析執行緒
- 由分號引起的問題
- 執行緒安全引起的錄音雜音電流音問題執行緒
- Spring中多執行緒的使用及問題Spring執行緒
- 非同步/同步,阻塞/非阻塞,單執行緒/多執行緒概念梳理非同步執行緒
- 關於js執行緒問題的解讀JS執行緒
- 執行緒的讓步與阻塞執行緒
- java執行緒的五大狀態,阻塞狀態詳解Java執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(下)伺服器模型執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(中)伺服器模型執行緒
- 探究Spring中Bean的執行緒安全性問題SpringBean執行緒
- 執行緒池的阻塞佇列的理解執行緒佇列
- ArrayList 的執行緒安全問題執行緒
- 單執行緒-非阻塞-長連結執行緒
- 關於redis單執行緒的分析Redis執行緒
- SQL執行計劃異常引起的效能問題SQL
- SQL執行計劃異常 引起的效能問題SQL
- 有個關於多執行緒的識別問題執行緒
- 深入解析 TiFlash丨多併發下執行緒建立、釋放的阻塞問題執行緒
- parallelStream中的執行緒安全問題Parallel執行緒
- J2SE - 關於SimpleDateFonnat的執行緒安全問題執行緒
- 單例模式中可能存在的一些問題(執行緒安全問題)單例模式執行緒
- 第15篇 執行緒鎖的問題執行緒
- 模板方法中的執行緒安全問題執行緒
- lambda中stream執行緒安全的問題執行緒
- Java 執行緒安全問題的本質Java執行緒
- 關於執行緒池的面試題執行緒面試題
- 單例模式執行緒安全reorder問題單例模式執行緒
- 執行緒中斷以及執行緒中斷引發的那些問題執行緒
- 子執行緒使用父執行緒RequestScope作用域Bean問題的探究執行緒Bean
- Java執行緒的狀態Java執行緒
- 對執行緒、協程和同步非同步、阻塞非阻塞的理解執行緒非同步
- 多執行緒Demo學習(執行緒的同步,簡單的執行緒通訊)執行緒
- iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用iOS執行緒GC
- 企圖使用c++執行緒解決nodejs單執行緒問題C++執行緒NodeJS
- 關於Java多執行緒的執行緒同步和執行緒通訊的一些小問題(順便分享幾篇高質量的博文)Java執行緒
- Java BlockingQueue 阻塞佇列[用於多執行緒]JavaBloC佇列執行緒
- 一個由於侵入框架引起的故障框架
- ThreadLocal執行緒重用時帶來的問題thread執行緒