由於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執行緒
- 由於內部連線引起的Oracle RAC效能問題Oracle
- 關於js執行緒問題的解讀JS執行緒
- 執行緒的讓步與阻塞執行緒
- java執行緒的五大狀態,阻塞狀態詳解Java執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(中)伺服器模型執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(下)伺服器模型執行緒
- 伺服器模型——從單執行緒阻塞到多執行緒非阻塞(上)伺服器模型執行緒
- 執行緒池的阻塞佇列的理解執行緒佇列
- 請教一個關於執行緒的問題執行緒
- 關於執行緒的問題,清高手指點執行緒
- 單執行緒-非阻塞-長連結執行緒
- ArrayList 的執行緒安全問題執行緒
- 問題:執行緒的終止執行緒
- 多執行緒鎖的問題執行緒
- 請教一個涉及到多執行緒的關於單例的問題執行緒單例
- 關於redis單執行緒的分析Redis執行緒
- 關於jdon框架 in-memery 模式的狀態和執行緒問題框架模式執行緒
- 探究Spring中Bean的執行緒安全性問題SpringBean執行緒
- 有個關於多執行緒的識別問題執行緒
- 關於線上檢測主執行緒卡頓的問題執行緒
- 關於執行緒插入函式如何用的問題執行緒函式
- 請教關於執行緒的結束問題,急!!!執行緒
- 簡單的執行緒同步問題:兩個執行緒交替執行N次【Synchronized、Lock、ArrayBlockingQueue】執行緒synchronizedBloC
- 由optimizer_switch所引起的詭異問題
- 由row cache lock等待事件引起的效能問題事件
- 深入解析 TiFlash丨多併發下執行緒建立、釋放的阻塞問題執行緒
- jQuery同步Ajax帶來的UI執行緒阻塞問題及解決辦法jQueryUI執行緒
- 執行緒6--執行緒的狀態執行緒
- 關於執行緒池的面試題執行緒面試題
- SQL執行計劃異常引起的效能問題SQL
- SQL執行計劃異常 引起的效能問題SQL