iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >浅谈springboot如何保证多线程安全
  • 360
分享到

浅谈springboot如何保证多线程安全

2024-04-02 19:04:59 360人浏览 薄情痞子

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

摘要

目录如何保证多线程安全1.SpringBoot在多线程并发访问下是怎么做的2.controller在多线程下如何尽可能保证线程安全,如何取舍3.小结一下单例模式与线程安全问题踩的坑下

如何保证多线程安全

1.springboot在多线程并发访问下是怎么做的

我们在Controller下,一般都是@AutoWired一些Service,由于这些Service都交给了spring进行管理,因此他们单例的,对于在Controller中调用他们的方法,由于方法在JVM中属于栈操作,所以对于每一个线程来说,栈都是独立的,因此是线程安全的。

而由于Controller本身是单例模式 (非线程安全的), 这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。

如果我们定义了一个全局的实例,如 private Company company = new Company(); 而在@RequestMapping方法中去用到了他, 这里就存在并发线程安全的问题。

对于所有的请求request,这个company对象是相通的。

当然我们也可以用这个特性来制作访问计数器 只需要定义一个private int cout = 0; 在每一次请求后cout++;

当然我并不推荐这么做,计数器最好用Redis来操作。

总结以上问题,不要在Controller里出现类的实例。即便加了线程安全操作,也会出现性能问题。当然无论是Controller还是Service,如果你一定要使用对象的属性,如private Company company = new Company();可以加上ThreadLocal的引用,如private ThreadLocal<Company> tc = new ThreadLocal<>();但是把这种使用的对象放进方法中初始化(即进入JVM栈中更好)。

2.controller在多线程下如何尽可能保证线程安全,如何取舍

当多个请求对controller进行请求时,它的instance的单例模式是线程不安全的,因此我们如果要保证完全的线程安全,需要对于每次请求都创建一个新的controller实例,在spring中使用@RequestScope注解定义它的作用域为requst,即一次请求即为一个实例,这样就可以保证controller层面上的线程安全。但是这样做会有一个很大的缺点,就是这种方式当并发很大时,创建bean的新实例就比重用原有的controller实例要慢许多。

因此还有折中的办法,就是将@RequestScope设置为session级别的作用域,这样每当一次会话,spring就会创建一个controller实例,而不需要每次请求都去创建一次实例,大大提高了访问的速度,虽然这样无法保证绝对的线程安全,但是在大部分的业务逻辑上都有效的防止了线程安全的问题。

此外,spring的作用域还有singleton(单例,也是spring默认的作用域级别,即永远使用同一个实例)、prototype(原型)、globalSession(全局)

3.小结一下

Spring本身并没有解决并发访问的问题。如果bean的范围不是线程安全的(例如在controller上面的成员变量或者静态变量就是线程不安全的),但其方法包含一些您总是希望安全运行的关键代码或者使用了静态字段需要对其进行并发修改,请在该方法上使用synchronized关键字。或者使用一些有提供线程安全的集合进行相应的多线程操作。

单例模式与线程安全问题踩的坑

最近有客户反映,使用公司产品时,偶尔会存在崩溃情况,自己测试无问题,然后去查日志,是报空指针。于是顺藤摸瓜 往上找,好嘛,之前的开发使用了成员变量,感觉问题就是在这里了,因为众所周知,springboot 采用的是单例模式,所以,使用成员变量时一定要谨慎。

下面上一张该类的截图

大家可能看到了,该类上面加上了@Scope("prototype") 注解,该注解的作用是将该类变成多例模式。讲道理因为变为了多例,应该不会有线程问题了。

我先说下我这边的一个代码环境

上面大家看到的BaseController这个类里面有个init方法,会在继承它的类的所有方法前执行。

使用的是@ModelAttribute注解,这个注解的意思是,在该controller的所有方法前执行,意在初始化,我猜测之前的同事应该是为了获取相同的一些参数,抽调出来做一个父类,随着迭代,别的同事为了方便,拿来就用,导致很多controller继承了该类。

@Scope("prototype")注解:大家设想一下,若父类加了@Scope("prototype")注解,子类controller并没有加该注解,会怎样呢?该注解是否还有意义?再比如,我在某service上加上@Scope("prototype")注解,但调用的controller没有加@Scope("prototype")注解,那么会出现什么样的结果呢?大家可以去测试一下,测试方法也很简单,就是在对应的父类或service的无参构造方法里打印该类的地址。

下面说下我的测试结果

先说父类上加了@Scope("prototype")注解,子类上没有加这种情况。结果是,同一子类继承的为同一父类,不同子类继承为不同父类。理解一下,很简单,因为springboot为单例模式,所以子类为单例,那么只有一个子类,父类肯定是一样的。所以,不同线程过来使用的为同一变量,就会有问题。

同理:在service上标注@Scope("prototype")注解,那在同一个controller里,该service还是同一个,也就是说还是单例的,在不同的controller里 是不同的。测试方法同上。

现在说下解决方法

1、是在继承该controller的子类上都加上@Scope("prototype")注解。这样做的好处是简单。坏处也同样明显,因为是多例的,那么就会产生大量的实体类,占用大量内存,若是回收不及时,有可能会出现内存溢出。

2、是将变量私有化,比如使用线程变量,对变量加等,技术上会复杂一些,而且调试不太好调试。说不定那些地方就会出现问题,毕竟是老代码。

3、将该类转换为拦截器,将变量放入request里,用的时候取出来。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 浅谈springboot如何保证多线程安全

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 浅谈springboot如何保证多线程安全
    目录如何保证多线程安全1.springboot在多线程并发访问下是怎么做的2.controller在多线程下如何尽可能保证线程安全,如何取舍3.小结一下单例模式与线程安全问题踩的坑下...
    99+
    2024-04-02
  • springboot怎么保证多线程安全
    小编给大家分享一下springboot怎么保证多线程安全,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!如何保证多线程安全1.springboot在多线程并发访问下是怎么做的我们在Controller下,一般都是@AutoW...
    99+
    2023-06-22
  • java多线程怎么保证线程安全
    Java中有多种方式可以保证线程安全,以下是一些常见的方法:1. 使用synchronized关键字:使用synchronized关...
    99+
    2023-09-13
    java
  • ConcurrentHashMap是如何保证线程安全
    目录JDK 1.7 底层实现JDK 1.7 线程安全实现JDK 1.8 底层实现JDK 1.8 线程安全实现总结ConcurrentHashMap 是 HashMap 的多线程版本,...
    99+
    2024-04-02
  • 详解CopyOnWriteArrayList是如何保证线程安全
    目录一:前言二:成员变量分析三:源码分析1.空参构造2.传入一个Collection对象的构造方法3.传入一个数组的构造方法四:总结一:前言 在我们需要保证线程安全的时候,如果使用到...
    99+
    2024-04-02
  • 浅谈java线程状态与线程安全解析
    目录1.线程的几种状态1.1 线程的状态1.2 线程状态的转移 2.有关线程安全问题2.1 一个简单的例子2.2 造成线程不安全的原因1.线程的几种状态 1.1 线程的状态...
    99+
    2023-02-03
    java线程状态 java线程安全
  • 浅谈如何保证Mysql主从一致
    目录binlog的三种格式对比为什么会有mixed格式的binlog? 循环复制问题小结       ...
    99+
    2024-04-02
  • 浅谈单例模式和线程安全问题
    目录单例模式、多实例模式、和线程安全单例模式懒汉式和饿汉式对比多线程模式下的安全性多实例模式总结单例模式、多实例模式、和线程安全 单例模式 单例模式是指确保一个类仅有一个唯一的实例,...
    99+
    2023-05-14
    java单例模式 java线程安全
  • 浅谈Java中ArrayList线程不安全怎么办
    ArrayList线程不安全怎么办? 有三种解决方法: 使用对应的 Vector 类,这个类中的所有方法都加上了 synchronized 关键字 就和 HashMap ...
    99+
    2024-04-02
  • 高并发怎么保证线程安全
    线程安全有原子性、可见性、有序性这3个方面,我们可以从这三个方面入手,可以通过加锁来保证线程安全,如果对象是immutable,则是线程安全,可放心使用,也可以使用synchronized关键字来保证线程安全。...
    99+
    2024-04-02
  • 在java程序中怎么保证多线程的运行安全
    java程序中保证多线程运行安全的方式:使用安全类,比如 Java. util. concurrent 下的类。使用自动锁 synchronized。使用手动锁 Lock。保证一个或者多个操作在CPU执行的过程中不被中断。保证一个线程对共享...
    99+
    2024-04-02
  • 详解SpringBoot是如何保证接口安全的
    目录为什么要保证接口安全防篡改如何解决防重放基于timestamp的方案基于nonce + timestamp 的方案代码实现1、构建请求头对象2、工具类从HttpServletRe...
    99+
    2023-02-02
    SpringBoot保证接口安全 SpringBoot 接口安全
  • 如何保证小程序的安全性
    要保证小程序的安全性,可以采取以下措施: 使用合法的开发工具和平台:确保使用官方或可信赖的开发工具和平台进行小程序开发,避免使用...
    99+
    2024-04-17
    小程序
  • Go语言atomic.Value如何不加锁保证数据线程安全?
    目录引言atomic.Value的使用方式atomic.Value的内部实现写入线程安全的保证读取(Load)操作总结引言 很多人可能没有注意过,在 Go(甚至是大部分语言)中,一条...
    99+
    2023-05-20
    Go语言atomic.Value Go数据线程安全
  • 分布式下redis怎么保证线程安全
    在分布式环境下,Redis本身是单线程模型的,因此不需要额外的线程安全措施。然而,在使用Redis的客户端与服务器进行通信时,可能需...
    99+
    2023-10-25
    redis
  • Java中的同步机制:如何确保多线程安全?
    在Java中,多线程的应用非常广泛。然而,多线程同时访问共享资源时,很容易引起数据竞争等问题,导致程序出现未知的错误。因此,在多线程编程中,保证线程安全非常重要。Java提供了多种机制来实现线程同步,本文将介绍Java中的同步机制及其应用...
    99+
    2023-11-09
    同步 numy 日志
  • Java对象的内存分配过程是如何保证线程安全的
    本篇内容介绍了“Java对象的内存分配过程是如何保证线程安全的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在开始进入正题之前,请允许我问一...
    99+
    2023-06-16
  • Java多线程编程安全如何退出线程
    小编给大家分享一下Java多线程编程安全如何退出线程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!线程停止Thread提供了一个stop()方法,但是stop()...
    99+
    2023-05-30
    java
  • Win XP远程控制时如何保证安全
    跟其他远程控制技术类似,远程协助和远程桌面同样要在使用前考虑好安全问题。对于最高级别的安全要求,根本不建议在实际应用中使用远程控制技术,不过要明白这种技术也能给用户带来便利。本章会就使用远程控制技术时保证安全性的方法进行...
    99+
    2023-05-24
    Win XP远程控制 保证安全 XP
  • Java 同步和 IDE 的奇妙冒险:如何在多线程环境下保证数据安全?
    在现代计算机系统中,多线程编程已成为不可避免的技术之一。但是,多线程编程对于程序员来说也带来了新的挑战,其中一个挑战就是如何在多线程环境下保证数据安全。Java 提供了一种机制来帮助解决这个问题,那就是同步。 Java 同步机制是一种基于...
    99+
    2023-06-26
    同步 ide http
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作