最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年07月04日 09:26:19   作者:aitangyong  
這篇文章主要給大家介紹了關(guān)于spring容器初始化時候遇到的死鎖問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

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

解決過程:

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

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

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

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

來看一段例子,這個例子和我們項(xiàng)目中實(shí)際代碼很相似。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配置文件和啟動代碼如下,運(yùn)行可以發(fā)現(xiàn)出現(xiàn)死鎖:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd">
 
 
 <bean id="config" class="net.aty.spring.deadlock.ConfigHelper"></bean>
 <bean id="first" class="net.aty.spring.deadlock.FirstBean"></bean>
 <bean id="second" class="net.aty.spring.deadlock.SecondBean"></bean>
 
</beans>
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提供的一些擴(kuò)展點(diǎn)處(BeanFactoryAware/InitializingBean等),開啟線程去獲取bean,很容器出現(xiàn)死鎖。因?yàn)閟pring初始化單例bean(大多數(shù)bean都是單例的)會加鎖。如果初始化1個bean的時候,還沒有釋放鎖,另一個線程再次觸發(fā)spring加載bean,就會出現(xiàn)死鎖。

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

<bean id="config" class="net.aty.spring.deadlock.ConfigHelper" depends-on="second"></bean>
<bean id="first" class="net.aty.spring.deadlock.FirstBean" depends-on="config"></bean>
<bean id="second" class="net.aty.spring.deadlock.SecondBean"></bean>

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 基于java構(gòu)造方法Vector創(chuàng)建對象源碼分析

    基于java構(gòu)造方法Vector創(chuàng)建對象源碼分析

    這篇文章主要介紹了java構(gòu)造函數(shù)中對Vector源碼及原理的分析,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪
    2021-09-09
  • MyBatis-Plus中Service接口的lambdaUpdate用法及實(shí)例分析

    MyBatis-Plus中Service接口的lambdaUpdate用法及實(shí)例分析

    本文將詳細(xì)講解MyBatis-Plus中的lambdaUpdate用法,并提供豐富的案例來幫助讀者更好地理解和應(yīng)用該特性,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java開發(fā)HashMap?key必須實(shí)現(xiàn)hashCode?equals方法原理

    Java開發(fā)HashMap?key必須實(shí)現(xiàn)hashCode?equals方法原理

    這篇文章主要為大家介紹了Java開發(fā)HashMap?key必須實(shí)現(xiàn)hashCode?equals方法原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java實(shí)現(xiàn)字符串和輸入流的相互轉(zhuǎn)換

    Java實(shí)現(xiàn)字符串和輸入流的相互轉(zhuǎn)換

    這篇文章主要介紹了Java實(shí)現(xiàn)字符串和輸入流的相互轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Spring boot文件路徑映射配置代碼實(shí)例

    Spring boot文件路徑映射配置代碼實(shí)例

    這篇文章主要介紹了Spring boot文件路徑映射配置代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • Java NIO Buffer過程詳解

    Java NIO Buffer過程詳解

    這篇文章主要介紹了Java NIO Buffer過程詳解,緩沖區(qū)在java nio中負(fù)責(zé)數(shù)據(jù)的存儲。緩沖區(qū)就是數(shù)組。用于存儲不同數(shù)據(jù)類型的數(shù)據(jù)。,需要的朋友可以參考下
    2019-06-06
  • 詳解Java如何實(shí)現(xiàn)有效的并發(fā)處理

    詳解Java如何實(shí)現(xiàn)有效的并發(fā)處理

    隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,現(xiàn)代軟件系統(tǒng)對于并發(fā)性能的要求越來越高,如何學(xué)習(xí)和掌握并發(fā)編程技術(shù)成為了Java開發(fā)人員必備的技能之一,本文主要介紹了Java并發(fā)編程的相關(guān)概念、原理和實(shí)踐技巧,感興趣的可以了解下
    2023-11-11
  • 解決SpringBoot2多線程無法注入的問題

    解決SpringBoot2多線程無法注入的問題

    這篇文章主要介紹了解決SpringBoot2多線程無法注入的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • java教程散列表和樹所對應(yīng)容器類及HashMap解決沖突學(xué)習(xí)

    java教程散列表和樹所對應(yīng)容器類及HashMap解決沖突學(xué)習(xí)

    本篇篇文章是java教程,主要介紹了java教程散列表,樹所對應(yīng)容器類及HashMap解決沖突的學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • Mybatis返回Map數(shù)據(jù)方式示例

    Mybatis返回Map數(shù)據(jù)方式示例

    這篇文章主要為大家介紹了Mybatis返回Map數(shù)據(jù)方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06

最新評論

钟祥市| 黄陵县| 武清区| 马边| 宜都市| 美姑县| 项城市| 平远县| 吉林市| 沙湾县| 灌云县| 尼木县| 阿巴嘎旗| 林州市| 泌阳县| 南宁市| 新巴尔虎左旗| 海城市| 浪卡子县| 广饶县| 龙南县| 阳泉市| 海宁市| 宿松县| 会同县| 黄冈市| 吉安市| 临海市| 丹东市| 卢氏县| 望都县| 郑州市| 阆中市| 郸城县| 定南县| 上林县| 定日县| 高淳县| 鲁甸县| 奉贤区| 民县|