返回顶部
首页 > 资讯 > 后端开发 > Python >Java中Spring的单例模式使用
  • 392
分享到

Java中Spring的单例模式使用

2024-04-02 19:04:59 392人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录1.spring单例V.S设计模式的单例2.成员变量的解决方式3.Spring并发问题4.对实体bean在多线程中的处理5.spring无状态的支持6.spring有状态的支持7

1.spring单例 V.S 设计模式的单例

  • 设计模式单例,在整个应用中只有一个实例
  • spring单例,在一个ioc容器中只有一个实例

spring中的单例也不影响应用并发访问。大多数时候客户端都在访问我们应用中的业务对象,为减少并发控制,不应该在业务对象中设置那些容易造成出错的成员变量。

2.成员变量的解决方式

  • 方法的参数,局部变量(相当于new)
  • threadlocal、设置bean scope=prototype

Spring Bean Scope 有状态的Bean与无状态的Bean

3.Spring并发问题

一般无状态的Bean才可在多线程环境下共享,Spring Bean默认为singleton作用域。

那有状态bean呢?Spring对一些如

  • RequestContextHolder
  • TransactionSynchronizationManager
  • LocaleContextHolder

非线程安全状态Bean采用ThreadLocal,让它们也成为线程安全的状态。

如用有状态bean,也可使用prototype模式,每次在注入时,就重新创建一个bean,在多线程中互不影响。

Eic-server所有的业务对象中的成员变量如:

  • Dao中的xxxDao
  • controller中的xxxService

都会被多个线程共享,那这些对象不会出现同步问题吗?比如造成DB插入,更新异常?

实体bean,从客户端传递到后台controller=》service=>Dao流程中,他们这些对象都是单例的,那这些单例对象在处理我们的传递到后台的实体bean不会出问题吗?(实体bean在多线程中的解决方案)
因为实体bean不是单例的,他们并没有交给Spring管理!每次我们都手动的New出来的,如BiGobject bo = new BigObject(),所以即使是那些处理我们提交数据的业务处理类是被多线程共享,但他们处理的数据并不共享,数据是每个线程都有自己的一份,所以在数据方面不会出现线程安全问题。

4.对实体bean在多线程中的处理

  • 对实体bean一般通过方法参数的的形式传递(参数是局部变量),所以多线程间不会有影响
  • 有的地方对有状态的bean直接使用prototype
  • 对使用bean的地方,可通过new创建
  1. 在Dao中的xxxDao
  2. controller中的xxxService

这些对象都是单例,那就不会出现线程同步问题。这些对象虽被多线程并发访问,可我们访问的是他们里面的方法,而这些类里面通常不会有成员变量。所以出问题的是系统里面的业务对象,务必注意这些业务对象里,千万不能有独立的成员变量,否则会出错。

所以我们在应用中的业务对象如下:

controller中的成员变量List和paperService:

service里的成员变量ibatisEntityDao:

虽然这个应用有成员变量,但不会出现线程安全问题:

  • controller里的成员变量private TestPaperService papersService 之所以会成为成员变量,我们的目的是注入,将其实例化进而访问里面的方法
  • private static final int List = 0;是final的不会被改变
  • service里面的private IbatisEntityDao ibatisEntityDao;是框架本身的,线程同步问题已解决

5.spring无状态的支持

Spring框架对单例的支持是采用单例注册表。

6.spring有状态的支持

spring如何实现那些个有状态bean,如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder]的线程安全,即使用ThreadLocal实现的

  • Spring中ThreadLocal的使用

7.ThreadLocal

当使用ThreadLocal维护变量(仅是变量,因为线程同步问题就是成员变量的互斥访问出问题)时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每个线程都可独立改变自己的副本,而不会影响其它线程所对应副本。

从线程角度看,就好像每一个线程都完全拥有该变量,这其实就将共享变相为人手一份。虽使用ThreadLocal带来更多内存开销,但这点开销还微不足道。因为保存在ThreadLocal中的对象,通常较小。

initialValue(),protected的方法,为子类重写而实现。该方法返回当前线程在该线程局部变量的初始值,是个延迟调用方法,在一个线程第1次调用get()或set(Object)时才执行且仅执行1次。

8.ThreadLocal使用

要给线程初始化一个特殊值时,需要自己实现ThreadLocal的子类并重写该方法,通常使用一个内部匿名类对ThreadLocal进行子类化,

EasyDBO中创建jdbc连接上下文就是这样做的:

简单实现版本:

9.ThreadLocal V.S synchronized

为保证多个线程对共享变量的安全访问,通常会使用synchronized保证同时只有一个线程对共享变量进行操作。但有些情况下,synchronized不能保证多线程对共享变量的正确读写。

例如类有个类变量,该类变量会被多个类方法读写,当多线程操作该类的实例对象时,若线程对类变量有读取、写入操作就会发生类变量读写错误,即便是在类方法前加上synchronized也无效,因为同一个线程在两次调用方法之间时是被释放的,这时其它线程可访问对象的类方法,读取或修改类变量。这种情况下可以将类变量放到ThreadLocal中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。

多线程访问对于类变量和ThreadLocal变量的影响,QuerySvc分别设置:

  • 类变量sql
  • ThreadLocal变量

使用时先创建QuerySvc的一个实例对象,然后产生多个线程,分别设置不同sql实例对象,再调用execute,读取sql的值,看是否是set方法中写入的值。这类似WEB应用中多个请求线程携带不同查询条件对一个servlet实例的访问,然后servlet调用业务对象,并传入不同查询条件,最后要保证每个请求得到的结果是对应的查询条件的结果。

使用QuerySvc的工作线程如下:

运行线程:

先创建一个QuerySvc实例对象,然后创建若干线程来调用QuerySvc的set和execute方法,每个线程传入的sql都不一样,sql变量中值不能保证在execute中值和set设置的值一样,在web应用中就表现为一个用户查询的结果不是自己的查询条件返回的结果,而是另一个用户查询条件的结果。

而ThreadLocal中的值总是和set中设置的值一样,这样通过使用ThreadLocal获得了线程安全性。

小结:

若一个对象要被多个线程访问,而该对象存在类变量被不同类方法读写,为获得线程安全,可以用ThreadLocal替代类变量。

ThreadLocal和线程同步机制相比有什么优势呢?

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。

这时该变量是多个线程共享的,使用同步机制要分析:

  • 什么时候对变量进行读写
  • 什么时候需要锁定某个对象
  • 什么时候释放对象锁等繁杂的问题

ThreadLocal为每个线程提供一个独立变量副本,隔离多线程对数据的访问冲突。ThreadLocal采用“以空间换时间”。

10.Spring使用ThreadLocal解决线程安全问题

一般只有无状态Bean才能在多线程下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,有状态Bean就能在多线程中共享了。

一般Web应用划分为展现层、服务层和持久层三个层次,从接收请求到返回响应所经过的所有程序调用都同属于一个线程。这就能根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。

ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

到此这篇关于Java中Spring的单例模式使用的文章就介绍到这了,更多相关Spring的单例模式使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中Spring的单例模式使用

本文链接: https://lsjlt.com/news/163075.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中Spring的单例模式使用
    目录1.spring单例V.S设计模式的单例2.成员变量的解决方式3.Spring并发问题4.对实体bean在多线程中的处理5.spring无状态的支持6.spring有状态的支持7...
    99+
    2024-04-02
  • Java中单例模式怎么用
    这篇文章给大家分享的是有关Java中单例模式怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。注意单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。优点在内存里只有一...
    99+
    2023-06-29
  • java设计模式中的单例模式简单介绍
    这篇文章主要介绍“java设计模式中的单例模式简单介绍”,在日常操作中,相信很多人在java设计模式中的单例模式简单介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java设计模式中的单例模式简单介绍”的疑...
    99+
    2023-06-02
  • 分析Java中的单例模式
    本篇内容主要讲解“分析Java中的单例模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析Java中的单例模式”吧!WHAT维基百科给出了解释、实现的思路以及应该注意的地方:单例模式,也叫单子...
    99+
    2023-06-25
  • Java中的单例模式实例分析
    本篇内容介绍了“Java中的单例模式实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、定义单例模式(Singleton Patter...
    99+
    2023-06-29
  • java中单例模式与Singleton
    前言这一篇来源我的公众号,如果你没看过,正好直接看看,如果看过了也可以再看看,我稍微修改了一些内容,今天讲解的内容如下:一、什么是单例模式【单例模式】,英文名称:Singleton Pattern,这个模式很简单,一个类型只需要一个实例,他...
    99+
    2021-08-10
    java教程 单例模式 Singleton
  • java中单例模式讲解
    目录WHATWHYHOW饿汉式实现一:静态实例参数与静态代码块实现二:静态内部类懒汉式错误一:单线程实现错误二:同步方法错误三:同步代码块之单次检查错误四:同步代码块之双重检查正确:...
    99+
    2024-04-02
  • Java中常用的设计模式之单例模式详解
    目录注意优点缺点使用场景一、实现方式二、实现方式三、测试总结注意 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 优点...
    99+
    2024-04-02
  • Java设计模式-单例模式
    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供...
    99+
    2023-06-05
  • spring的单例模式如何现实
    在Spring中,有多种方式来实现单例模式: 默认的单例模式:Spring容器默认情况下会将所有声明为Bean的对象作为单例对象...
    99+
    2024-02-29
    spring
  • web中怎么使用单例模式
    这篇文章主要为大家展示了“web中怎么使用单例模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“web中怎么使用单例模式”这篇文章吧。介绍单例模式,顾名思义就是...
    99+
    2024-04-02
  • PHP中如何使用单例模式?
    php 中的单例模式确保一个类只有一个实例,通过以下步骤实现:创建私有静态属性存储实例。创建私有构造函数防止直接实例化。创建公共静态方法用于获取实例;如果不存在则创建并存储为私有属性。 ...
    99+
    2024-05-21
    php 单例模式
  • 用实例分析Java单例模式
    这篇文章主要用实例分析Java单例模式,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。本文实例讲述了Java单例模式。分享给大家供大家参考,具体如下:在实际开发的时候会有一些需求,在某个类中只能...
    99+
    2023-05-31
    java 单例模式 ava
  • Java设计模式的单例模式实例分析
    本文小编为大家详细介绍“Java设计模式的单例模式实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java设计模式的单例模式实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是单例模式单例模式(S...
    99+
    2023-06-29
  • Java设计模式之单例模式
    目录什么是设计模式?单例模式是什么?单例模式设计的原则是什么?Java实现单例模式的5种方式?懒汉饿汉静态内部类双重校验锁DCL(Double Check Lock)枚举(num)总...
    99+
    2024-04-02
  • java中常见的几种单例模式
    这篇文章主要为大家展示了“java中常见的几种单例模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java中常见的几种单例模式”这篇文章吧。  单例模式:是一种常用的软件设计模式,在它的核心结...
    99+
    2023-06-19
  • Java中的四种单例模式浅析
    前言近期在做支付,一开始图省事,也是为了调试方便,支付的alipayClient和tradeService都是使用的时候去拿,这样就会导致创建多次。为了节省资源,统一配置成单例模式。什么是单例Singleton(单例)是设计模式的一种,为了...
    99+
    2023-05-31
    java 单例模式 ava
  • Spring bean配置单例或多例模式方式
    目录Spring bean配置单例或多例模式单例多例Spring scope配置单例、多例模式1、scope属性介绍2、scope配置3、单例模式底层实现模拟Spring bean配...
    99+
    2024-04-02
  • JAVA的单例模式实例分析
    这篇文章主要介绍“JAVA的单例模式实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JAVA的单例模式实例分析”文章能帮助大家解决问题。一、单例模式是什么?单例(Singleton)模式的定义...
    99+
    2023-06-29
  • java 单例模式的实例详解
    java 单例模式的实例详解概念:    java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。    单例模式有一下特点:   1、单例类只能有一个实例。   2、单例类必须自己自己创建自己的唯一...
    99+
    2023-05-31
    java 单例模式 ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作