IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring中bean的线程安全问题 -> 正文阅读

[Java知识库]spring中bean的线程安全问题

Bean的线程安全分析

  • 对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。
  • 对于singleton作用域的Bean,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的。

但是如果单例Bean是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。解释一下:

  • 无状态Bean(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。
  • 有状态Bean(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。

对于有状态的bean(比如Model和View),就需要自行保证线程安全, 解决办法就是:

  • 将有状态的bean的作用域由“singleton”改为“prototype”
  • 采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本

spring中bean的线程安全问题

结合Spring来理解,Spring的Bean默认都是单例的,那么会不会有线程安全的问题,要知道线程安全是针对不同用户之间对成员变量的操作互相影响导致的,换句话说如果你的类中没有非静态成员变量 ,即使有多个线程同时访问单例对象的成员方法也不会出问题,因为每个线程在栈和方法区中会有私有的存储空间,并不会导致数据混乱出现类似事务ACID的问题,写到这里大家可能已经明白了,线程安全只是针对全局变量的,如果是方法的话用同一个对象同时进行调用也不会出现安全问题。Service和DAO的实例对象大多数情况下只是作一个方法的调用,在Service的实现类中如果有全局变量怎么办呢?

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

同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。
ThreadLocal采用了“空间换时间”的方式。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。

有状态和无状态的对象区别

第一:基本概念

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

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

第二:看看代加深影响

/** 
 * 有状态bean,有state,user等属性,并且user有存偖功能,是可变的。 
 *  
 * @author Peter Wei 
 *  
 */ 
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;  
    }  
}  
/** 
 * 无状态bean,不能存偖数据。因为没有任何属性,所以是不可变的。只有一系统的方法操作。 
 *  
 * @author Peter Wei 
 *  
 */ 
public class StatelessBeanService {  
   
    // 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean.  
    BillDao billDao;  
   
    public BillDao getBillDao() {  
        return billDao;  
    }  
   
    public void setBillDao(BillDao billDao) {  
        this.billDao = billDao;  
    }  
   
    public List<User> findUser(String Id) {  
         return null;  
    }  
}  

第三:Spring中的有状态(Stateful)和无状态(Stateless)

  1. 通过上面的分析,相信大家已经对有状态和无状态有了一定的理解。无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。

  2. 默认情况下,从Spring bean工厂所取得的实例为singleton(scope属性为singleton),容器只存在一个共享的bean实例。

  3. 理解了两者的关系,那么scope选择的原则就很容易了:有状态的bean都使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

  4. 如Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是相当于不变(immutable)类,所以不影响。Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息的,在多线程环境下是不安全的,所以Struts2默认的实现是Prototype模式。在Spring中,Struts2的Action中,scope要配成prototype作用域。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-11 16:17:11  更:2022-05-11 16:18:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:57:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码