当前位置:首页 > 技术 >

spring线程安全问题解析(spring创建对象线程安全怎么解决)

来源:原点资讯(www.yd166.com)时间:2023-11-03 12:05:58作者:YD166手机阅读>>

来源:blog.csdn.net/jdk_wangtaida/article/details/88738228

前言

这是我在一次面试中被问到过的问题,但是当时我回答的并不是太好,最近在学习多线程知识的时候又对这个问题有了新的理解,所以这篇文章主要讲解下我对个问题的理解。

正文一、理解这个问题前,你需要先知道几个知识点

1.spring的bean作用域都有哪些?默认是哪个?

spring线程安全问题解析,spring创建对象线程安全怎么解决(1)

默认的是:单例 singleton

2.创建单例的方式是否线程安全与使用已经创建好的单例对象是否线程安全是两个问题

①常见创建单例的方式懒汉式和饿汉式

懒汉式(不安全写法)

public class Singleton{ private Singleton(){} private static Singleton singleton = null; //不建立对象 public static Singleton getInstance(){ if(singleton == null) { //先判断是否为空 singleton = new Singleton (); //懒汉式做法 } return singleton ; } }

饿汉式

public class Singleton{ public Singleton(){} private static Singleton singleton = new Singleton(); //建立对象 public static Singleton getInstance(){ return singleton ;//直接返回单例对象 }}

这两种创建方式中,懒汉式在多线程环境下就是线程不安全的,假设有线程1和线程2两个线程,线程1在判断if(singleton == null)的时候,突然失去cpu的执行权,而线程2获得了cpu的执行权,执行了getInstance()方法,创建了个对象,但是这个事情线程1并不知道,线程1重新获得cpu的执行权时,判断if(singleton == null)结果是null,所以又去创建了对象,那么这样就会出现破坏单例的情况,有多余的对象,所以线程是不安全的,解决方案之一就是加锁,代码如下

懒汉式(安全写法)

public class Singleton{ private Singleton(){} private static Singleton singleton = null; //不建立对象 public static synchronized Singleton getInstance(){ if(singleton == null) { //先判断是否为空 singleton = new Singleton (); //懒汉式做法 } return singleton ; } }

②在spring的框架里,对象是交给spring容器创建的,spring的创建单例的方式既不是懒汉式也不是饿汉式,是单例注册表模式实现单例模式的,感兴趣的可以看这篇文章:https://blog.csdn.net/u012794505/article/details/80926823,这种创建单例模式的方式是线程安全的。

③怎么判断使用已经创建好的单例对象是否线程安全

  • 看这个单例里有没有全局变量(全局变量就是成员变量,成员变量又分实例变量和静态变量)
  • 如果有全局变量,看它是不是只可以读取而不能写入(有没有发布set方法)

如果满足上面两个条件,那么这个单例就是不安全的。

二、spring的单例模式与线程安全

1.spring框架里的bean获取实例的时候都是默认单例模式,所以在多线程开发里就有可能会出现线程不安全的问题。当多个用户同时请求一个服务器时,容器(tomcat)会给每一个请求分配一个线程,这时多个线程会并发执行该请求所对应的业务逻辑(controller里的方法),此时就要注意啦,如果controller(是单例对象)里有全局变量并且又是可以修改的,那么就需要考虑线程安全的问题。解决方案有很多,比如设置@scope("prototype")为多例模式,为每个线程创建一个controller,还可以使用ThreadLocal。

2.其实spring的源码里比如RequestContextHolder、TransactionSynchronizationManager、LoxaleContextHolder等这些对象创建方式也是单例,底层就是用ThreadLocal处理的。ThreadLocal基本实现思路是:它会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,因为每个线程都拥有自己的变量副本,从而也就没必要对该变量进行同步啦。

spring线程安全问题解析,spring创建对象线程安全怎么解决(2)

3.在ssh或ssm框架里的service或dao对象虽然也是单例模式,但正如上面分析的,他们没有可修改的全局变量,所以在多线程环境下也是安全的。

4.其实在很多文章中对于spring的单例模式与线程安全会提到一个概念有状态对象和无状态对象,无状态对象在多线程环境下是线程安全的,有状态的对象则不是,其实这个字面的意思是比较对的,因为这个对象如果无法存储数据,也就不会出现多个线程操作共享数据的情况,自然安全,概念如下

有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。

无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象.不能保存数据,是不变类,是线程安全的。

但是很多文章举的无状态对象的例子我认为不合理。比如:https://blog.csdn.net/bingjing12345/article/details/9794945,因为如果这个对象没有set放方法只是可读,其实也是安全的。

public class StatefulBean { public int state; // 由于多线程环境下,user是引用对象,是非线程安全的 public User user; public int getState() { return state; } public void setState(int state) { this.state = state; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } } 总结

其实你越去了解框架底层的实现原理,你越会为这个框架的思想而着迷,你会感慨框架笔者的想法是多么的奇妙,多么的周全,多一字嫌多,少一字嫌少。

栏目热文

spring创建单例怎么保证线程安全(spring怎么解决线程安全问题)

spring创建单例怎么保证线程安全(spring怎么解决线程安全问题)

问题背景这段时间在做项目的时候,考虑到Spring中的bean默认是单例模式的,那么当多个线程调用同一个bean的时候就...

2023-11-03 11:21:48查看全文 >>

spring如何处理线程安全(spring如何处理多线程问题)

spring如何处理线程安全(spring如何处理多线程问题)

Spring与线程安全Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并...

2023-11-03 11:53:53查看全文 >>

如何解决spring线程安全问题(spring线程安全解决方法)

如何解决spring线程安全问题(spring线程安全解决方法)

专注于Java领域优质技术,欢迎关注作者:Java3y Java3y前言文本已收录至我的GitHub仓库,欢迎Star:...

2023-11-03 12:03:19查看全文 >>

spring怎么解决线程安全问题(spring是怎么保证线程安全的)

spring怎么解决线程安全问题(spring是怎么保证线程安全的)

点击上方 "程序员小乐"关注, 星标或置顶一起成长每天凌晨00点00分, 第一时间与你相约每日英文Goo...

2023-11-03 11:19:42查看全文 >>

spring 单例解决线程安全问题(spring解决线程安全问题)

spring 单例解决线程安全问题(spring解决线程安全问题)

一、Spring单例模式与线程安全Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线...

2023-11-03 11:20:27查看全文 >>

spring的单例线程安全(spring是怎么保证线程安全的)

spring的单例线程安全(spring是怎么保证线程安全的)

转自:riemann_链接:http://blog.csdn.net/riemann_/article/details/...

2023-11-03 11:52:58查看全文 >>

spring为什么要用线程安全(spring是怎么保证线程安全的)

spring为什么要用线程安全(spring是怎么保证线程安全的)

Spring与线程安全Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并...

2023-11-03 11:47:18查看全文 >>

戴口罩有必要化妆吗(长期戴口罩可以化妆吗)

戴口罩有必要化妆吗(长期戴口罩可以化妆吗)

来源:中国妇女报图集 自今年初新冠肺炎疫情暴发至今,人们戴口罩出行已成为常态,同时由“口罩脸”引发的各种皮肤问题也日益频...

2023-11-03 11:22:37查看全文 >>

戴口罩和化妆哪个更伤害皮肤(长期戴口罩化妆好还是不化妆好)

戴口罩和化妆哪个更伤害皮肤(长期戴口罩化妆好还是不化妆好)

南都讯记者李榕新冠疫情爆发后,“口罩脸”成为很多爱美人士的痛处,脸泛油光、爆痘、皮肤过敏……所有的皮肤问题都让口罩“背锅...

2023-11-03 11:36:07查看全文 >>

化妆可以整天戴口罩吗(戴口罩适合化妆吗)

化妆可以整天戴口罩吗(戴口罩适合化妆吗)

我是行走的匠人,关注我,变美不迷路。复古和开学后,肯定是口罩不离身,平时上课出门都要戴口罩,戴口罩的时候也只会露出来我们...

2023-11-03 11:33:42查看全文 >>

文档排行