日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring框架中的单例Bean是线程安全的吗?

發布時間:2025/3/12 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring框架中的单例Bean是线程安全的吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先直接給出答案:不是線程安全的

一、分析問題

證明不是線程安全的案例如下:

public class Student {private String stuName;public String report(String uname){stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;} } ----------------------------------------------------------------------------------------------------------------- public class Run {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);Student bean1 = context.getBean(Student.class);new Thread(() -> {System.out.println(bean1.report("張三"));}).start();Student bean2 = context.getBean(Student.class);new Thread(() -> {System.out.println(bean2.report("李四"));}).start();} }


分析原因:線程一執行完stuName的賦值后進入休眠,線程二這時候也進入該方法對stuName進行賦值,由于對象是單例的,線程二的賦值操作也就影響了線程一的打印結果。導致最后打印的結果都是線程二傳入的值。

二、解決方法

既然單例bean不是線程安全的,那么該怎么解決上面的問題呢?下面博主給出四種解決方法僅供讀者參考:

1.方法一:將成員變量放入方法中

修改后的Student類如下:

public class Student { // private String stuName;public String report(String uname){String stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;} }

2.方法二:加鎖使方法串行執行

比如下面的方法中我加入了synchronized鎖:

public class Student {private String stuName;public synchronized String report(String uname){stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;} }

3.方法三:將bean變成原型模式

比如加上Scope注解聲明為多例模式:

@Bean@Scope("prototype")public Student student(){return new Student();}

4.方法四:使用ThreadLocal

改造后的代碼如下:

public class Student {private ThreadLocal<String> stuName = new ThreadLocal<>();public String report(String uname){stuName.set("大家好,我叫:"+uname);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName.get();} }

總結

以上是生活随笔為你收集整理的Spring框架中的单例Bean是线程安全的吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。