Spring Singleton mode and thread safety

Source: Internet
Author: User
Tags dateformat string format

    • Issue background

This time while doing the project, considering that the bean in spring is in singleton mode by default, there is a thread safety problem when multiple threads invoke the same bean. If the bean creation pattern in spring is non-singleton, there is no such problem.

    • Spring Singleton mode and thread safety

The bean in the Spring framework, or the component, is the default singleton mode when it comes to getting instances, which is especially important in the case of multithreaded development. The singleton pattern means that there is only one instance. The singleton pattern ensures that a class has only one instance, and instantiates itself and provides this instance to the system as a whole. This class is called a singleton class.

When multiple users request a service at the same time, the container assigns a thread to each request, which is the same business logic (member method) that multiple threads execute concurrently with the request, and it is important to note that thread synchronization issues must be taken into account if there is a modification to that single-column state in that processing logic, which is reflected as a member property of that single

Comparison of synchronization mechanisms: what are the advantages of ThreadLocal compared to the thread synchronization mechanism? Both the threadlocal and thread synchronization mechanisms are designed to address the access violation of the same variable in multiple threads.

In the synchronization mechanism, the lock mechanism of the object guarantees 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 variables, when to lock an object, when to release object locks and other complex problems, programming and writing is relatively difficult.

ThreadLocal, however, solves multiple threads of concurrent access from another angle. ThreadLocal provides a separate copy of the variable for each thread, isolating the access violation of 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 that can encapsulate unsafe variables into threadlocal when writing multithreaded code.

Because the ThreadLocal can hold any type of object, the Get () provided by the lower version of the JDK returns an object, which requires a type cast. But JDK 5.0 solves this problem well by generics, simplifying the use of ThreadLocal to some extent. In the case of multi-threaded resource sharing, the synchronization mechanism uses the "time-to-space" approach, while ThreadLocal uses the "space-for-time" approach. The former provides only one copy of the variable, allowing different threads to queue access, and 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 troubleshoot thread safety issues. We know that in general, only stateless beans can be shared in a multithreaded environment, and in Spring, most beans can be declared as singleton scopes. It is because Spring uses a non-thread-safe state for some beans (such as Requestcontextholder, Transactionsynchronizationmanager, Localecontextholder, etc.) ThreadLocal are processed to make them also a thread-safe state, because stateful beans can be shared across multiple threads.

The general Web application divides into the presentation layer, the service layer and the persistence layer three levels, writes the corresponding logic in the different layers, the lower layer through the interface to the upper layer open function calls. In general, all program calls from receiving requests to returning responses belong to one thread.

ThreadLocal is a good idea to solve thread safety problems by providing a separate copy of the variable for each thread to solve the conflicting problem of variable concurrency access. In many cases, ThreadLocal is easier and more convenient than using the synchronized synchronization mechanism to solve thread safety problems, and results programs have higher concurrency.

If your code is in a process where multiple threads are running at the same time, these threads may run the code at the same time. If the result of each run is the same as the single-threaded run, and the value of the other variable is the same as expected, it is thread-safe.  Or, the interface provided by a class or program for a thread is an atomic operation or a switchover between multiple threads does not result in ambiguity in the execution of the interface, that is, we do not have to consider the problem of synchronization. Thread safety issues are caused by global variables and static variables.

In general, this global variable is thread-safe if there are only read operations for global variables and static variables in each thread, and if multiple threads are concurrently performing write operations, it is generally necessary to consider thread synchronization, which may affect thread safety.

1) constants are always thread-safe because only read operations exist.

2) Creating a new instance before each call to the method is thread safe because the shared resource is not accessed.

3) Local variables are thread-safe. Because each execution of a method creates a local variable in a separate space, it is not a shared resource. Local variables include the parameter variables of the method and the in-method variables.

A state is a data storage function. Stateful objects (Stateful beans), which are objects with instance variables, can hold data that is non-thread safe. No state is preserved between different method invocations.

Stateless is a single operation and cannot hold data. A stateless object (stateless Bean) is an object that has no instance variable. Cannot save data, is immutable class, is thread safe.

Stateful objects:

Stateless beans are suitable for invariant patterns, and technology is a singleton mode, which allows you to share instances and improve performance. Stateful beans, which are unsafe in multithreaded environments, are suitable for use with the Prototype prototype model. Prototype: A new bean instance is created each time a request is made to the bean.

STRUTS2 The default implementation is Prototype mode. That is, each request is reborn as an Action instance, so there is no thread safety issue. It is important to note that if the life cycle of the action is managed by Spring, scope is to be paired with the prototype scope.

    • Thread Safety Cases

There is a Calendar object reference inside the SimpleDateFormat (SDF) class that is used to store date information related to this SDF, such as Sdf.parse (DATESTR), Sdf.format (date), and so forth Parameters passed in date-related String, date, and so on, are all dating Calendar is used to store. This can lead to a problem, if your SDF is static, then multiple thread will share this SDF, but also share the Calendar reference, and, observing the Sdf.parse () method, you will find a The following call:

1 Date Parse () {2   //  Cleanup Calendar3   //  perform some actions, set calendar date for what's 4   //  Get calendar time 5}

The problem here is that if thread A calls Sdf.parse () and Calendar.clear () is not executed Calendar.gettime (), then thread B calls Sdf.parse (), and  Thread B also executes the Sdf.clear () method, which causes the calendar data for thread A to be emptied (in fact, A/b is emptied at the same time). Or when a executes a calendar.clear () and is suspended, then B begins to call Sdf.parse () and ends with a smooth I, so that the date stored in A's calendar becomes a later B-setting Calen Date of Dar

There is a more important problem behind this question-stateless: one of the benefits of a stateless approach is that it can be safely invoked in a variety of environments. To measure whether a method is stateful, see if it changes something else, such as a global variable, such as an instance field. The Format method changes the Calendar field of the SimpleDateFormat during the run, so it is stateful.

This also reminds us to note the next three points when developing and designing the system:

1. When you write a common class, make a clear explanation of the consequences of the multi-threaded call case in the comments

2. Be aware of thread safety for each shared mutable variable in a threaded environment

3. Our classes and methods are designed to be as stateless as possible.

    • Solutions

1. Create a new instance when needed:

Note: When you need to use a new instance of SimpleDateFormat, you can avoid multithreading problems whenever you change the thread security problem object from shared to local private, but it also adds to the burden of creating objects. In general, this is actually less noticeable than the performance impact.

2. Using sync: Synchronizing SimpleDateFormat objects

1 Public classDatesyncutil {2Private StaticSimpleDateFormat SDF =NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); 3 4 Public StaticString formatdate (date date)throwsparseexception{5synchronized(SDF) {6returnSdf.format (date);7         }   8     } 9 10 Public StaticDate Parse (String strdate)throwsparseexception{11synchronized(SDF) {12returnSdf.parse (strdate);13         }14     } 15}
Note: When a thread calls this method when a thread is many, other threads that want to call this method will block, and multithreading concurrency can have a certain effect on performance.

3. Use ThreadLocal:

1 Public classConcurrentdateutil {2Private StaticThreadlocal<dateformat> ThreadLocal =NewThreadlocal<dateformat>() { 3@Override4protectedDateFormat InitialValue () {5return NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); 6         } 7     }; 8 Public StaticDate Parse (String datestr)throwsParseException {9returnThreadlocal.get (). Parse (DATESTR);10     }11 Public StaticString Format (date date) {12returnthreadlocal.get (). Format (date);13     }14}

Or

1 threadlocal<dateformat>(); 2 3 Public StaticDateFormat GetDateFormat ()4     {   5 DateFormat df =Threadlocal.get (); 6if(df==NULL){   7 DF =NewSimpleDateFormat (Date_format); 8Threadlocal.set (DF); 9         }  10returnDF; 11     }  12 Public StaticString formatdate (date date)throwsParseException {13returnGetDateFormat (). Format (date);14     }15 Public StaticDate Parse (String strdate)throwsParseException {16returnGetDateFormat (). Parse (strdate);17     }   18}

Description: Using ThreadLocal, the shared variable is also changed to exclusive, the thread exclusive can be compared to the method exclusive in the concurrency environment can reduce the cost of many objects created. This approach is generally recommended if performance requirements are high.

4. Discard the JDK and use the time formatting classes from other class libraries:

1. Using Apache Commons Fastdateformat, claiming to be both fast and thread-safe simpledateformat, unfortunately it can only format the date, cannot parse the date string.

2. Use the Joda-time class library to handle time-related issues

To do a simple stress test, the method of the slowest, method three the fastest, but even the slowest method a performance is not bad, the general system method one and the method two can be satisfied, so that in this point is difficult to become the bottleneck of your system. From a simple point of view, it is recommended to use method one or method two, if necessary, the pursuit of a bit of performance improvement, you can consider using method three, with ThreadLocal cache.

Joda-time class Library is perfect for time processing, it is recommended.

Spring Singleton mode and thread safety

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.