最近面试遇到一个问题:单例 Bean 的线程安全问题怎么解决的。

之前了解但是没有深究它的解决方法。大部分时候我们并没有在项目中使用多线程,所以很少有人会关注这个问题。

大部分 Bean 实际都是无状态(没有实例变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。

因为Spring 默认情况下是单例的(singleton)。所有我们会遇见多个线程操作同一个对象的时候是存在资源竞争的问题。

常见的有两种解决办法:

  1. 在 Bean 中尽量避免定义可变的成员变量。

  2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

    ​ 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

      而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。不同线程只操作自己线程的副本变量。

    ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal

    ThreadLocal代码举例

     private  static ThreadLocal<Integer> content=new ThreadLocal<Integer>(){
    
             protected  Integer initalValue(){
    return (int)(Math.random()*10+100);
    } }; private static ThreadLocal<Integer> test=new ThreadLocal<Integer>(){ protected String initalValue(){
    return "单例模式是不安全的" +(int)(Math.random()*10+100);
    }
    };
    public Object get(){
    System.out.println(content.get());
    System.out.println(test.get());
    System.out.println();
    return test.get();
    }
  3. 将有状态的bean的作用域由“singleton”改为“prototype”。( 如注解 : @Scope("prototype") );

  4. 使用线程同步,加关键字synchronized。对多线程性能有一定影响(此方法没试验过 慎用!);

单例 Bean 的线程安全问题的更多相关文章

  1. Spring单例Bean和线程安全

    Spring的bean默认都是单例的,这些单例Bean在多线程程序下如何保证线程安全呢?例如对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Sevlet线程来处理请求,引入Spring框 ...

  2. Spring框架中的单例bean是线程安全的吗?

    不,Spring框架中的单例bean不是线程安全的.

  3. Spring 框架中的单例 bean 是线程安全的吗?

    不,Spring 框架中的单例 bean 不是线程安全的.

  4. Spring bean 和单例bean的线程安全

    Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).prototype(原型).request.session和global session,5种作用域说 ...

  5. spring单例bean是线程安全的吗?

    如果在你不定义成员变量的情况下,spring默认是线程安全的 否则,设置scope="prototype"

  6. Spring框架中的单例Beans是线程安全的么?

    Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和 ...

  7. 【Spring】8、Spring框架中的单例Beans是线程安全的么

    看到这样一个问题:spring框架中的单例Beans是线程安全的么? Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上, ...

  8. Spring框架中的单例Beans是线程安全的么

    Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和 ...

  9. 5.2:缓存中获取单例bean

    5.2  缓存中获取单例bean 介绍过FactoryBean的用法后,我们就可以了解bean加载的过程了.前面已经提到过,单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例 ...

  10. 【Spring源码分析】非懒加载的单例Bean初始化过程(上篇)

    代码入口 上文[Spring源码分析]Bean加载流程概览,比较详细地分析了Spring上下文加载的代码入口,并且在AbstractApplicationContext的refresh方法中,点出了f ...

随机推荐

  1. jmeter 从多个数中随机取一个值的方法

    问题描述:使用jmeter进行接口测试时,遇到枚举值(如:10代表闲置.15代表使用中.20代表维修等)我们需要随机取一个类型传到接口中. 解决思路:通过函数助手查找随机函数,找到__chooseRa ...

  2. [HNCTF]Web详解_原创

    WEB Challenge__rce 根据给出的源代码来看典型的命令执行但是正则匹配掉说有的字母只留下数字和少量字符串. 根据大佬给出的思路使用自增绕过 <?php error_reportin ...

  3. 教你用Python制作BMI计算器

    案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用Python相关知识,做一个BMI计算器的案例.你可以通过控制台的提示信息,输入身高和体重,注意单位,系统会自动计算出BMI ...

  4. [.NET学习]EFCore学习之旅 -2 简单的增删改查

    1.实例化创建数据库上下文类 首先实例化一个数据库操作上下文类,注意到DbContext实现了IDisposable接口,所以使用using语句,避免内存泄露. 2.插入 以Person类为例,先生成 ...

  5. Java单例模式的最佳实践?

    "读过书,--我便考你一考.茴香豆的茴字,怎样写的?"--鲁迅<孔乙己> 0x00 大纲 目录 0x00 大纲 0x01 前言 0x02 单例的正确性 new关键字 c ...

  6. day35-JSON&Ajax03

    JSON&Ajax03 4.jQuery的Ajax请求 原生Ajax请求问题分析: 编写原生的Ajax要写很多的代码,还要考虑浏览器兼容问题,使用不方便 在实际工作中,一般使用JavaScri ...

  7. ADB命令快速入门

    什么是ADB adb的全称为Android Debug Bridge,就是起到调试桥的作用.通过adb我们可以方便调试Android程序. 环境搭建 1需要java环境: 安装完JDK需要配置环境变量 ...

  8. Django重点及面试题

    Django 简述python三大主流web框架 """ django 大而全,类似于航空母舰 但是有时候过于笨重 flask 小而精,类似于游骑兵(单行代码就可以起一个 ...

  9. LFU 的设计与实现

    LFU 的设计与实现 作者:Grey 原文地址: 博客园:LFU 的设计与实现 CSDN:LFU 的设计与实现 题目描述 LFU(least frequently used).即最不经常使用页置换算法 ...

  10. day11-功能实现10

    家居网购项目实现010 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 24.bugFix-添加购物车按钮动态处理 24.1需求 ...