Possible errors of spring singleton under high concurrency

Possible errors of spring singleton under high concurrency

 

Possible errors of spring singleton under high concurrency: First, only when the injected object is stateless and idempotent can it be guaranteed that it will not be modified before and after execution, otherwise the singleton object will change after one execution, and the next execution It is possible to cause different results. It will appear in the case of high concurrency. This thread has just used the singleton object to set attributes. If it has not been used, another process has already modified the attributes of the data of the singleton object. Completed, the singleton obtained by the distant thread is a dirty object that cannot be used. When the singleton object contains variable variable data, it cannot be injected in the form of object injection. What should I do? 1. Create a new object in the singleton object, which belongs to the thread's own memory to store data, and other threads cannot use it The latter object is not practical singleton object 3. Lightweight creation of local variables through new Callable() can use context variables, which belong to the thread's own variables Summary: In the case of high concurrency, the data of simple interest objects cannot be stored in a thread Used, the data of the singleton object changes when another thread calls it. In fact, the singleton object is equivalent to a global variable. The data needs to be modified when the thread executes. In the case of high concurrency, the singleton object data obtained by the current thread will be dirty data.

 

Spring singleton and thread safety summary

1. Spring singleton pattern and thread safety

 

 
The beans in the Spring framework, or components, are in the default singleton mode when obtaining instances, which is something that should be paid special attention to in multi-threaded development.

 

The singleton pattern means that there is only one instance. The singleton pattern ensures that there is only one instance of a class, and it instantiates itself and provides this instance to the entire system. This class is called a singleton class.
When multiple users request a service at the same time, the container will assign a thread to each request, which means that multiple threads will concurrently execute the business logic (member method) corresponding to the request. If there is a modification to the state of the single column (represented as a member attribute of the single column), the thread synchronization problem must be considered
Comparison of synchronization mechanisms What are the advantages of ThreadLocal compared to thread synchronization mechanisms? Both ThreadLocal and thread synchronization mechanisms are designed to solve the access conflict problem of the same variable in multiple threads. 
 
  In the synchronization mechanism, the lock mechanism of the object ensures that only one thread accesses the variable at the same time. At this time, the variable is shared by multiple threads. Using the synchronization mechanism requires the program to carefully analyze when to read and write the variable, when to lock an object, and when to release the object lock and other complicated issues. Program design and writing relatively difficult. 
 
  ThreadLocal solves the concurrent access of multiple threads from another perspective. ThreadLocal will provide each thread with an independent copy of the variable, thereby isolating the access conflict of multiple threads to the data. Since each thread has its own copy of the variable, there is no need to synchronize the variable. ThreadLocal provides thread-safe shared objects. When writing multi-threaded code, unsafe variables can be encapsulated into ThreadLocal. 
 
  Since any type of object can be held in ThreadLocal, the get() provided by the lower version of JDK returns an Object object, which requires type conversion. But JDK 5.0 solves this problem well through generics, simplifying the use of ThreadLocal to a certain extent
 To sum up, for the problem of multi-threaded resource sharing, the synchronization mechanism adopts the method of "exchanging time for space", while ThreadLocal adopts the method of "exchanging space for time". The former only provides a variable for different threads to queue for access, while the latter provides a variable for each thread, so it can be accessed at the same time without affecting each other. 
 
  Spring uses ThreadLocal to solve thread safety problems 
 
  We know that in general, only stateless beans can be shared in a multi-threaded environment. In Spring, most beans can be declared as singleton scope. It is because Spring uses ThreadLocal to process non-thread-safe states in some beans (such as RequestContextHolder, TransactionSynchronizationManager, LocaleContextHolder, etc.), making them thread-safe, because stateful beans can be shared among multiple threads. 
 
  一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程
ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。 
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。  线程安全问题都是由全局变量及静态变量引起的。  
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
1) 常量始终是线程安全的,因为只存在读操作。 
2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象  ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象  .不能保存数据,是不变类,是线程安全的。
有状态对象:
无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。
Struts2默认的实现是Prototype模式。也就是每个请求都新生成一个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326938916&siteId=291194637