首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

【Spring】IOC容器并发条件上,可能发生死锁

2012-09-07 
【Spring】IOC容器并发条件下,可能发生死锁1.背景 ?代码十分简单,如下:?package com.alibaba.testimport or

【Spring】IOC容器并发条件下,可能发生死锁

1.背景

?

代码十分简单,如下:

?【Spring】IOC容器并发条件上,可能发生死锁【Spring】IOC容器并发条件上,可能发生死锁
    package com.alibaba.test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class DeadLockTest { ClassPathXmlApplicationContext context = null; public void startContext() { context = new ClassPathXmlApplicationContext(); context.setConfigLocation("spring/bean/mybeans.xml"); context.refresh(); } public void getBean() { new Thread(new GetBean()).start(); } /** * @param args */ public static void main(String[] args) { DeadLockTest t = new DeadLockTest(); //get bean 工作线程 t.getBean(); //容器启动主线程 t.startContext(); } //get bean 工作线程 class GetBean implements Runnable { public void run() { try { Thread.sleep(10000); MyBean myBean = (MyBean) context.getBean("myBean"); myBean.getOtherBean().sayHello(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // TODO Auto-generated method stub } }}

    ?

    其中mybean定义如下(一定要用注解的注入方式,才会有可能发生死锁!):

    ?

    ?【Spring】IOC容器并发条件上,可能发生死锁【Spring】IOC容器并发条件上,可能发生死锁
      package com.alibaba.test;import org.springframework.beans.factory.annotation.Autowired;public class MyBean { @Autowired private OtherBean otherBean; public OtherBean getOtherBean() { return otherBean; } public void setOtherBean(OtherBean otherBean) { this.otherBean = otherBean; } public void sayHello() { otherBean.sayHello(); }}

      ?

      myBean.xml:

      ?【Spring】IOC容器并发条件上,可能发生死锁【Spring】IOC容器并发条件上,可能发生死锁
        <?xml version="1.0" encoding="GB2312"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"><beans default-autowire="byName"><bean/><bean id="myBean" /></beans>

        ?

        以上代码经过调试控制,即会发生思索,控制如下:

        1.main线程在DefaultListableBeanFactory.preInstantiateSingletons 方法的

        synchronized (this.beanDefinitionMap) {

        ...

        }里加个断点

        2.getBean工作线程在DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory singletonFactory)方法的

        synchronized (this.singletonObjects) {

        ...

        }里加个断点。

        3.等1,2断点都进去之后,再触发继续运行,就会发生死锁。

        ?

        结论也许可以算是 spring 的 bug ,也许可以算我们使用不当。

        ?

        总之,有两点需要注意:

        1.?????? 尽量避免显式调用 ioc 容器,注入工作由容器自己来完成。

        2.?????? 尽量在容器初始化完,开始对外服务。

热点排行