• 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 的线程安全。


    原文链接
     


     

  • 相关阅读:
    android 入门-Service
    android 入门-Activity及 字体
    android 入门-安装环境
    PS 零基础训练1
    wp8 入门到精通 ImageCompress 图片压缩
    wp8 入门到精通 Gallery
    C# DateTime时间格式转换为Unix时间戳格式
    wp8 入门到精通 MultiMsgPrompt
    C# Func<T,TResult>
    redis简介
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12123256.html
Copyright © 2020-2023  润新知