Spring为什么是单例的?如何保证线程安全? 您所在的位置:网站首页 单例的线程安全问题 Spring为什么是单例的?如何保证线程安全?

Spring为什么是单例的?如何保证线程安全?

2024-01-05 16:10| 来源: 网络整理| 查看: 265

单例的好处:

1 减少请求时候创建对象的开销,提升性能

2 减少jvm垃圾回收

单例的坏处:

1 对于有状态的变量可能会造成线程安全问题,因为只有一个实例,如果操作的是有状态的全局变量,多个线程之间可能会操作同一个变量和对象导致线程不安全问题

 

多例的好处:

1 线程安全,每个请求过来都分配一个新的对象,里面的所有东西属性方法都是该线程独享的

坏处:

1 资源开销大,创建对象需要消耗性能

2 会产生大量的垃圾对象

 

Spring框架中的bean 或者说组件,默认是单例的。 单例模式确保了某个类只有一个实例,并且自行实例化,向整个系统提供这个实例。 在多线程的情况下,Web容器会向每个请求分配一个线程。这些线程会执行对应的业务逻辑。如果在执行的时候对单例对象进行了修改,则必须考虑到线程同步的问题。 同步机制 ThreadLocal 和 线程同步机制   线程同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题。   ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。 对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。  在spring 中是使用 ThreadLocal 解决线程安全问题 线程安全问题主要是全局变量和静态变量引起的。 若每个线程中对全局变量、静态变量读操作,而无写操作,一般来说这个全局变量是线程安全的。 若多个线程同时执行写操作,需要考虑线程同步问题,否则影响线程安全。 spring 使用ThreadLocal 实现高并发下 共享资源的同步。 原理:   为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线  程都完全拥有该变量。【每个线程其实是改变的是自己线程的副本,而不是真正要改变的变量,所以效果就是每个线程都有自己的,“这其实就将共享变相为人人有份!”】  ThreadLocal 如何实现为每一个变量维护变量的副本。

public void set(T value) {     Thread t = Thread.currentThread();     ThreadLocalMap map = getMap(t);     if (map != null)         map.set(this, value);     else         createMap(t, value); }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有