真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何解決spring容器初始化遇到的死鎖問題

小編給大家分享一下如何解決spring容器初始化遇到的死鎖問題,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

我們提供的服務(wù)有:網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、蔡甸ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的蔡甸網(wǎng)站制作公司

前言

最近啟動spring項目的時候遇到一個死鎖問題,使用jstack獲取線程堆棧的時候,可以看到2個線程出現(xiàn)了死鎖:

如何解決spring容器初始化遇到的死鎖問題

解決過程:

DefaultSingletonBeanRegistry.getSingleton()源碼如下,可以看到這個方法需要對singletonObjects加鎖

如何解決spring容器初始化遇到的死鎖問題

第二處xxx.subject.core.cache.DataLocalcacheInit.afterPropertiesSet源碼如下:

如何解決spring容器初始化遇到的死鎖問題

可以看到:這個bean在初始化的時候,會開啟線程,調(diào)用另外一個bean的initData()方法從數(shù)據(jù)庫加載數(shù)據(jù)。等數(shù)據(jù)加載完畢,DataLocalcacheInit這個bean的初始化才算完成。

通過上面的堆??梢钥闯觯簊pring容器在初始化bean的時候,會對singletonObjects對象加鎖;我們自己在afterPropertiesSet()方法中開啟了一個線程,最終也會觸發(fā)spring加載另外的bean。第一個線程(初始化spring的main線程)還沒有釋放鎖,第二個線程(自己開啟的線程),也需要獲取singletonObjects對象鎖,這樣就出現(xiàn)了死鎖。表現(xiàn)出來的現(xiàn)象就是:spring容器卡在那里,不能完成所有bean的初始化。

來看一段例子,這個例子和我們項目中實際代碼很相似。FirstBean調(diào)用ConfigHelper中的方法:

public class FirstBean implements InitializingBean {
 
 @Override
 public void afterPropertiesSet() throws Exception {
  System.out.println("first bean is initializing....");
 
  BlockingQueue queue = new ArrayBlockingQueue(10);
  Thread thread = new Thread() {
 
   @Override
   public void run() {
    ConfigHelper.doSomething();
    queue.add(1);
   }
  };
 
  thread.start();
 
  queue.take();
  System.out.println("first get data....");
 
 }
}

ConfigHelper代碼如下:通過BeanFactory獲取到另外一個bean

public class ConfigHelper implements BeanFactoryAware {
 private static BeanFactory factory;
 
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  this.factory = beanFactory;
 }
 
 public static void doSomething()
 {
  SecondBean bean = (SecondBean)factory.getBean("second");
  bean.say();
 }
}

SecondBean代碼很簡單如下:

public class SecondBean {
 public void say() {
  System.out.println("SecondBean....");
 }
}

spring配置文件和啟動代碼如下,運行可以發(fā)現(xiàn)出現(xiàn)死鎖:



 
 
 
 
 
 

public class Main {
 public static void main(String[] args) {
  ApplicationContext context = new FileSystemXmlApplicationContext(
    "src/main/java/net/aty/spring/deadlock/deadlock.xml");// 加載 spring 配置文件
 
 }
}

如何解決spring容器初始化遇到的死鎖問題

spring初始化的時候,如果我們在spring提供的一些擴展點處(BeanFactoryAware/InitializingBean等),開啟線程去獲取bean,很容器出現(xiàn)死鎖。因為spring初始化單例bean(大多數(shù)bean都是單例的)會加鎖。如果初始化1個bean的時候,還沒有釋放鎖,另一個線程再次觸發(fā)spring加載bean,就會出現(xiàn)死鎖。

解決上面的問題很簡單:FirstBean邏輯上是依賴于ConfigHelper和SecondBean的,但是我們卻并沒有顯示地告訴spring這種邏輯關(guān)系。spring初始化FirstBean的時候,進入afterPropertiesSet() ,這個方法開啟了線程會觸發(fā)另外2個bean的加載。我們只要顯示地告訴spring這種依賴關(guān)系,讓spring先加載ConfigHelper和SecondBean就可以了。



如何解決spring容器初始化遇到的死鎖問題

以上是“如何解決spring容器初始化遇到的死鎖問題”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)站題目:如何解決spring容器初始化遇到的死鎖問題
分享URL:http://weahome.cn/article/jgoghh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部