In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Most people do not understand the knowledge points of this "Spring thread safety case analysis in SingleTon mode" article, so the editor summarizes the following contents, detailed contents, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "Spring thread safety case analysis in SingleTon mode" article.
1. Stateful bean and stateless bean
Stateful bean: each user has its own unique instance. During the user's lifetime, bean saves the user's information, that is, stateful; once the user dies (call ends or instance ends), the lifetime of bean ends. That is, each user will initially get an initial bean.
Once the stateless bean:bean is instantiated, it is added to the session pool and can be shared by all users. Even if the user is dead, the lifetime of the bean may not necessarily end, and it may still exist in the session pool for other users to call. Since there is no specific user, then the state of a user cannot be maintained, so it is called stateless bean. But a stateless session bean is not stateless if it has its own properties (variables).
Statefulness is the function of data storage. Stateful objects (Stateful Bean), that is, objects with instance variables, can hold data and are not thread safe. No state is retained between different method calls.
Statelessness is an operation that cannot save data. Stateless objects (Stateless Bean) are objects that do not have instance variables, cannot save data, are immutable classes, and are thread safe.
In the Bean configuration of Spring, there are two situations:
Of course, there are not only two values for scope, but also request, session, and so on. However, singleton singletons and prototype polymorphisms are most commonly used.
Singleton indicates that there is only one instance of the bean globally, and the scope of bean in Spring is also singleton by default.
Prototype indicates that each time the bean is injected, a new instance is created, which applies to stateful Bean.
Here is an example of a stateful Bean
Public class TestManagerImpl implements TestManager {private User user; public void deleteUser (User e) throws Exception {user = e; / / 1 prepareData (e);} public void prepareData (User e) throws Exception {user = getUserByID (e.getId ()); / / 2 / / use user.getId (); / / 3}}
What happens if the Bean is configured as singleton?
If there are two users accessing, both call the Bean, assuming user1, user2.
When user1 is called to step 1 in the program, the private variable user of the Bean is assigned to user1, and when the program of user1 reaches step 2, the private variable user of the Bean is re-assigned to user1_create. Ideally, when user1 reaches step 3, the private variable user should be user1_create But if user2 starts to run to step 1 before user1 calls to step 3, the private variable user is modified to user2 because of singleton resource sharing. In this case, the user.getId () used in step 3 of user1 actually uses the object of user2.
Configuring stateful bean to singleton will cause resource confusion (thread safety problem), but if it is prototype, there will be no resource sharing problem, that is, there will be no thread safety problem.
Note: if your code is in a process where multiple threads are running at the same time, these threads may be running this code at the same time. If the result of each run is the same as that of a single thread, and the values of other variables are the same as expected, then the code is thread-safe.
Through the above analysis, we already have a certain understanding of statelessness and statelessness. Stateless Bean is suitable for immutable mode, and the technology is singleton mode, which can share instances and improve performance. Stateful Bean is not safe in multithreaded environment, so it is suitable to use Prototype prototype mode (solving multithreading problem), each request to bean will create a new bean instance.
2. Single example in Spring
The singleton in Spring is slightly different from the singleton in the design pattern, which has only one instance in the entire application, while the singleton in Spring has only one instance in an IOC container.
Most of the time, clients are accessing business objects in our application. In order to reduce concurrency control, we should not set member variables that are prone to errors in business objects at this time. During concurrent access, these member variables will be shared objects in the concurrent thread, and an unexpected situation will occur at this time.
Resolution of member variables:
Parameter local variables of the method (new in the method)
Use Threadlocal
Set the scope=prototype of bean
3. Spring uses ThreadLocal to solve thread safety problems.
As an IOC container, Spring helps us manage a lot of bean. But in fact, Spring does not guarantee the thread safety of these objects, so it is necessary for developers to write their own code to solve thread safety problems.
When using Spring, many people may wonder why DAO and Service objects in Spring adopt a single instance approach. These readers think so.
The DAO object must contain a database connection Connection, and this Connection is not thread-safe, so each DAO must contain a different Connection object instance, so the DAO object cannot be a single instance.
The above view is half right. The correct statement is that "each DAO should contain a different instance of the Connection object", but the wrong thing is "the DAO object cannot be a single instance". In fact, Spring uses the class ThreadLocal when implementing Service and DAO objects, which is the core of everything!
ThreadLocal
Each thread has its own ThreadLocalMap class object, in which the thread can keep its own object, and each thread can access its own object correctly.
Take a common static instance of ThreadLocal as a key, save the references of different objects to the ThreadLocalMap of different threads, and then get the object saved by the thread through the get () method of the static ThreadLocal instance everywhere the thread executes, thus avoiding the trouble of passing this object as a parameter.
General Web applications are divided into three layers: presentation layer, service layer and persistence layer. The corresponding logic is written in different layers, and the lower layer opens the function call to the upper layer through the interface. In general, all program calls from receiving the request to returning the response belong to the same thread. In this way, you can store some non-thread-safe variables in ThreadLocal as needed, and all associated objects refer to the same variable in the calling thread of the same request and response.
The following example reflects Spring's transformation of stateful Bean:
Public class TopicDao {/ / ① A non-thread-safe variable private Connection conn; / / ② refers to the non-thread-safe variable public void addTopic () {Statement stat = conn.createStatement ();}}
Because conn at ① is a member variable, because the addTopic () method is not thread-safe, you must create a new TopicDao instance (not singleton) when you use it. Let's use ThreadLocal to transform the non-thread-safe state of conn:
Public class TopicDao {/ / ① uses ThreadLocal to save the Connection variable private static ThreadLocal connThreadLocal = newThreadLocal (); public static Connection getConnection () {/ / ② if connThreadLocal does not have the corresponding Connection for this thread, create a new Connection, / / and save it to the thread-local variable. If (connThreadLocal.get () = = null) {Connection conn = getConnection (); connThreadLocal.set (conn); return conn;} / / ③ directly returns the thread local variable return connThreadLocal.get () } public void addTopic () {/ / ④ gets the corresponding Connection try {Statement stat = getConnection () .createStatement () from ThreadLocal;} catch (SQLException e) {e.printStackTrace ();}
When using TopicDao, different threads first determine whether connThreadLocal is null. If it is null, it means that the current thread does not have a corresponding Connection object, and then create a Connection object and add it to the local thread variable. If it is not null, it means that the current thread already has a Connection object and can use it directly. This ensures that different threads use thread-related Connection instead of other threads' Connection. Therefore, this TopicDao can be shared by singleton.
Both DAO and Service in Spring exist in the form of single instance bean. Spring makes stateful variables (such as database connection Connection) locally threaded through the ThreadLocal class, so as to make it safe in the case of multithreading. In the processing thread of a request response, the thread runs through the three layers of presentation, service and data persistence, and makes all the associated objects refer to the same variable through ThreadLocal.
Of course, this example itself is very rough, put the ThreadLocal of Connection directly in DAO can only achieve multiple methods of this DAO share Connection without thread safety problems, but can not share the same Connection with other DAO, to achieve the same transaction multiple DAO share the same Connection, you must use ThreadLocal to save Connection in a common external class.
Web applications are divided into presentation layer, service layer and persistence layer. XxxService is introduced as a member variable in controller and xxxDao is introduced as a member variable in xxxService. These objects are singletons and can be accessed concurrently by multiple threads, but we access the methods in them. These classes usually do not contain member variables. Dao instances are encapsulated in ORM frameworks such as MyBatis, have been tested, and there will be no thread synchronization problems. So the problem is the business objects in our own system, so we must pay attention to the custom business objects must not appear independent member variables, otherwise there will be thread safety problems.
Usually our business object in the application is as follows: controller has member variables list and paperService.
Public class TestPaperController extends BaseController {private static final int list = 0; @ Autowired @ Qualifier ("papersService") private TestPaperService papersService; public Page queryPaper (int pageSize, int page,TestPaper paper) throws EicException {RowSelection localRowSelection = getRowSelection (pageSize, page); List paperList = papersService.queryPaper (paper,localRowSelection); Page localPage = new Page (page, localRowSelection.getTotalRows (), paperList); return localPage;}}
The member variable ibatisEntityDao is introduced into service.
@ SuppressWarnings ("unchecked") @ Service ("papersService") @ Transactional (rollbackFor = {Exception.class}) public class TestPaperServiceImpl implements TestPaperService {@ Autowired @ Qualifier ("ibatisEntityDao") private IbatisEntityDao ibatisEntityDao; private static final String NAMESPACE_TESTPAPER = "com.its.exam.testpaper.model.TestPaper"; private static final String BO_NAME [] = {"examination paper warehouse"}; private static final String BO_NAME2 [] = {"examination paper configuration questions"} Private static final String BO_NAME1 [] = {"examination paper type"}; private static final String NAMESPACE_TESTQUESTION= "com.its.exam.testpaper.model.TestQuestion"; public List queryPaper (TestPaper paper,RowSelection paramRowSelection) throws EicException {try {return (List) ibatisEntityDao.queryForListWithPage (NAMESPACE_TESTPAPER, "queryPaper", paper,paramRowSelection);} catch (Exception e) {e.printStackTrace () Throw new EicException (e, "eic", "0001", BO_NAME);}
As can be seen from the above example, although our application contains member variables, there is no thread synchronization problem. The member variable papersService in controller is injected to access the method of the service class. The injected member variable ibatisEntityDao in papersService is encapsulated by the ORM framework, and the thread synchronization problem has been solved.
4. Comparison between ThreadLocal and thread synchronization mechanism.
What are the advantages of ThreadLocal over thread synchronization? Both ThreadLocal and thread synchronization mechanisms are designed to solve the access conflicts of the same variables in multiple threads.
In the synchronization mechanism, the object locking mechanism ensures that only one thread accesses the variable at a time. At this time, the variable is shared by multiple threads, and the use of synchronization mechanism requires the program to carefully analyze complicated problems such as when to read and write the variable, when to lock an object, when to release the object lock, and so on. Program design and writing is relatively difficult.
On the other hand, ThreadLocal solves the concurrent access of multi-thread from another point of view. ThreadLocal provides an independent copy of variables for each thread, thus isolating access conflicts from multiple threads to the data. Because each thread has its own copy of the variable, there is no need to synchronize the variable. ThreadLocal provides thread-safe shared objects, and unsafe variables can be encapsulated in ThreadLocal when writing multithreaded code.
Because any type of object can be held in ThreadLocal, the get () provided by the earlier version of JDK returns an Object object and requires a cast. 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-thread 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 provides only one 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.
ThreadLocal is a good way to solve the problem of thread safety. It solves the conflict of concurrent access of variables by providing an independent copy of variables for each thread. In many cases, ThreadLocal is simpler and more convenient to solve thread safety problems than using synchronized synchronization mechanism directly, and the resulting program has higher concurrency.
The above is about the content of this article on "thread safety case analysis of Spring in SingleTon mode". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.