zoukankan      html  css  js  c++  java
  • spring中的bean是线程安全的吗?

    Spring 不保证 bean 的线程安全。
    默认 spring 容器中的 bean 是单例的。当单例中存在竞态条件,即有线程安全问题。如下面的例子

    计数类

    package constxiong.interview.threadsafe;
     
    /**
     * 计数类
     * @author ConstXiong
     * @date 2019-07-16 14:35:40
     */
    public class Counter {
     
        private int count = 0;
        
        public void addAndPrint() {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(++count);
        }
        
    }

    spring 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
            
        <bean id="counter" class="constxiong.interview.threadsafe.Counter" />
        
    </beans>

    测试类

    package constxiong.interview.threadsafe;
     
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class CounterTest {
        
        public static void main(String[] args) {
            final ApplicationContext context = new ClassPathXmlApplicationContext("spring_safe.xml");
     
            for (int i = 0; i <10; i++) {
                new Thread(){
                    @Override
                    public void run() {
                        Counter counter = (Counter)context.getBean("counter");
                        for (int j = 0; j <1000; j++) {
                            counter.addAndPrint();
                        }
                    }
                }.start();
            }
            
        }
        
    }

    打印结果开头和结尾

    1
    5
    7
    4
    2
    6
    3
    8
    9
    .
    .
    .
    9818
    9819
    9820
    9821
    9822
    9823
    9824
    9825

    修改 spring 配置文件,把 bean 的作用域改为 prototype

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
            
        <bean id="counter" class="constxiong.interview.threadsafe.Counter" scope="prototype"/>
        
    </beans>

    测试结果输出10个 1000

    即每个线程都创建了一个 Counter 对象,线程内独自计数,不存在线程安全问题。但是不是我们想要的结果,打印出 10000。

    所以 spring 管理的 bean 的线程安全跟 bean 的创建作用域和 bean 所在的使用环境是否存在竞态条件有关,spring 并不能保证 bean 的线程安全。


    原文链接
     


     

  • 相关阅读:
    67. Add Binary
    66. Plus One
    64. Minimum Path Sum
    63. Unique Paths II
    How to skip all the wizard pages and go directly to the installation process?
    Inno Setup打包之先卸载再安装
    How to change the header background color of a QTableView
    Openstack object list 一次最多有一万个 object
    Openstack 的 Log 在 /var/log/syslog 里 【Ubuntu】
    Git 分支
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12123256.html
Copyright © 2011-2022 走看看