(2.1) servlet thread safety issues

Source: Internet
Author: User

This article refers to the link: http://www.yesky.com/334/1951334.shtml

absrtact : This paper introduces the servlet multithreading mechanism, through an instance and the Java memory model to explain the reason that the servlet thread is unsafe, gives three kinds of solutions to ensure the servlet thread security, and explains the trade-offs of three kinds of schemes in actual development.

Compared with ASP and PHP, servlet/jsp technology has high execution efficiency because of its multi-threaded operation. Because servlet/jsp is executed in multithreaded mode by default, you need to take a very careful look at the security of multithreading when writing code. However, many people do not pay attention to multithreading security issues when writing servlet/jsp programs, which often results in the program written by a small number of user access without any problems, and when the concurrent users rise to a certain value, there will be a lot of trouble.

-------------servlet is executed with multiple threads by default

Multithreading mechanisms for Servlets
The servlet architecture is built on the Java multithreading mechanism, whose life cycle is the responsibility of the Web container (Tomcat). When a client requests a servlet for the first time, the servlet container instantiates the Servlet class based on the Web. XML configuration file. When a new client requests the servlet, the servlet class is typically no longer instantiated, that is, multiple threads are using the instance. The servlet container automatically uses techniques such as the thread pool to support the operation of the system, as shown in 1.

In this way, when two or more threads access the same servlet at the same time, there may be situations where multiple threads concurrently access the same resource, and the data may become inconsistent. So if you are not aware of thread-safety issues when you build Web Apps with Servlets, you can make the servlet program you write difficult to find.
Thread safety issues for Servlets

The thread safety problems of servlets are mainly caused by improper use of instance variables, as illustrated by a practical example.

 Public classConcurrenttestextendshttpservlet {printwriter output; @Overrideprotected voidService (HttpServletRequest request, httpservletresponse response)throwsservletexception, IOException {String username; Response.setcontenttype ("text/html;charset=gb2312"); Username=request.getparameter ("username"); Output=Response.getwriter (); Try {            //to highlight concurrency problems, set a delay in thisThread.Sleep (5000); Output.println ("User name:" +username+ "<BR>"); } Catch(Exception e) {e.printstacktrace (); }    }}

An instance variable output is defined in the servlet, which is assigned to the user's output in the service method. When a user accesses the servlet, the program runs normally, but when multiple users are concurrently accessing it, it is possible that other users ' information will appear on other users ' browsers. This is a serious problem. In order to highlight the concurrency problem, it is easy to test and observe, we perform a delay operation when we echo the user information. Assuming that the servlet has been registered in the Web. XML configuration file, the existing two users A and B access the servlet simultaneously (you can start two IE browsers, or concurrently on both machines), which is also entered in the browser:

A:http://localhost:8080/servlettest/concurrenttest?username=a
B:http://localhost:8080/servlettest/concurrenttest?username=b

If User B is slightly slower than user A to enter, the output will be shown in 2:

Figure 2 A user and B user's browser output

As you can see from Figure 2, the Web server initiated two threads to process requests from User A and User B, but a blank screen was found on user A's browser, and user A's information was displayed on User B's browser. The servlet has a thread insecurity problem. Here we start by analyzing the memory model of the instance and observing the value of the instance variable output at different times to analyze the reason why the servlet thread is unsafe.
The memory model of Java JMM (Java memory models) JMM is primarily intended to prescribe some relationship between threads and memory. according to JMM's design, there is a main memory in the system, and all the instance variables in Java are stored in memory and shared for all threads. Each thread has its own working memory (working memory), the work is composed of two parts of the cache and the stack, the cache is a copy of the variables stored in main memory, the cache may not be the sum of main memory synchronization, that is, the changes in the cache variables may not be immediately written into main memory A thread's local variables are saved in the stack, and the variables in the stack cannot be accessed directly between the threads. According to JMM, we can abstract the memory model of the servlet instance discussed in this paper into the model shown in Figure 3.

The following is the memory model shown in Figure 3, to analyze when users A and B threads (referred to as a thread, b thread) concurrent execution, the changes involved in the servlet instance variables and the execution of the thread, 4 shows.

As can be seen clearly in Figure 4, the B thread's modification of the instance variable output overrides the change of the instance variable output by the a thread, resulting in user A's information being displayed on User B's browser. If the a thread executes the output statement, the B thread's modification to output has not been flushed to main memory, so the output shown in Figure 2 will not appear, so this is only an accidental phenomenon, but it increases the potential danger of the program.

Designing a thread-safe servlet
From the above analysis, we know that the incorrect use of instance variables is the main cause of the servlet thread insecurity. Here are three solutions for this problem and some reference suggestions for the selection of the scheme.
1. Implement Singlethreadmodel interface
This interface specifies how the system handles calls to the same servlet. If a servlet is specified by this interface, then the service method in this servlet will not have two threads being executed concurrently, and there is no thread-safe issue, of course. This method simply changes the class header definition of the previous concurrent test class to:

 Public class extends Implements Singlethreadmodel  {        ...  ...        }

Javax.servlet.SingleThreadModel API and its translation

Ensures that servlets handle only one request at a time. This interface has no methods.

Ensure that the servlet processes only one request at a time. The interface does not contain methods.

If a servlet implements this interface, you is guaranteed that no, the threads would execute concurrently in the S Ervlet ' s service method. The servlet container can make this guarantee by synchronizing access to a single instance of the Servlets, or by Maintaini ng a pool of servlets instances and dispatching each new request to a free servlet.

If the servlet implements the interface, it ensures that no two threads are executing the servlet's service method at the same time. The servlet container is guaranteed by synchronizing access to a single instance of the servlet, or by maintaining the instance pool of the servlet and assigning the new request to an idle servlet.

Note that Singlethreadmodel does isn't solve all thread safety issues. For example, session attributes and static variables can still is accessed by multiple requests on multiple threads at the Same time, even when Singlethreadmodel servlets is used. It is recommended that a developer take other means to resolve those issues instead of implementing this interface, such a s avoiding the usage of an instance variable or synchronizing the block of the code accessing those resources. This interface was deprecated in Servlet API version 2.4.

Note: Singlethreadmodel does not address all of the thread safety implications. for example, session properties and static variables can still be accessed simultaneously by multi-threaded multiple requests, even if the Singlethreadmodel servlet is used. It is recommended that developers take other measures to address these issues, rather than implementing the interface, such as avoiding the use of instance variables or synchronizing blocks of code while accessing resources. This interface will not be recommended in servlet API 2.4.

2. Synchronize the operation of the shared data
Using the Synchronized keyword ensures that only one thread can access the protected section at a time, and the servlet in this thesis can ensure thread security by synchronizing block operations. The code after synchronization is as follows:

 Public classConcurrenttestextendshttpservlet {printwriter output; @Overrideprotected voidService (HttpServletRequest request, httpservletresponse response)throwsservletexception, IOException {String username; Response.setcontenttype ("text/html;charset=gb2312"); Username=request.getparameter ("username"); synchronized( This) {Output=Response.getwriter (); Try {                //to highlight concurrency problems, set a delay in thisThread.Sleep (5000); Output.println ("User name:" +username+ "<BR>"); } Catch(Exception e) {e.printstacktrace (); }        }    }}

3. Avoid using instance variables
The thread safety problem in this example is caused by an instance variable, which is thread-safe as long as the instance variable is not used in any of the methods inside the servlet.
Fix the above servlet code, change the instance variable to local variable to implement the same function, the code is as follows:

 Public classConcurrenttestextendsHttpServlet {@Overrideprotected voidService (HttpServletRequest request, httpservletresponse response)throwsservletexception, IOException {printwriter output;        String username; Response.setcontenttype ("text/html;charset=gb2312"); Username=request.getparameter ("username"); synchronized( This) {Output=Response.getwriter (); Try {                //to highlight concurrency problems, set a delay in thisThread.Sleep (5000); Output.println ("User name:" +username+ "<BR>"); } Catch(Exception e) {e.printstacktrace (); }        }    }}

The above three methods are tested to show that they can be used to design a thread-safe servlet program.

If a servlet implements the Singlethreadmodel interface, the servlet engine will create a separate servlet instance for each new request, which will cause a lot of overhead. Singlethreadmodel is no longer advocated in the Servlet2.4;

Similarly, if you use synchronization in your program to protect the shared data that you want to use, the performance of the system is greatly reduced. This is because the code block that is being synchronized can only have one thread executing it at the same time, making it handle the throughput of customer requests at the same time, and many customers are in a blocking state. In addition, in order to ensure the consistency of the contents of main memory and the data of the thread, the cache can be refreshed frequently, which will greatly affect the performance of the system. Therefore, in the actual development should also avoid or minimize the synchronization code in the Servlet;

avoiding the use of instance variables in Serlet is the best choice for ensuring that the servlet thread is secure. from the Java memory model It is also known that the temporary variables in the method are allocated space on the stack, and each thread has its own private stack space, so they do not affect the thread's security.
Summary
A servlet's thread-safety problem is only apparent when there is a lot of concurrent access, and it is difficult to find, so pay special attention when writing a servlet program. Thread-safety issues are primarily caused by instance variables, so you should avoid using instance variables in Servlets. If application design cannot avoid using instance variables, use synchronization to protect the instance variables to be used, but to ensure the best performance of the system, you should synchronize the code path with the least availability.

(2.1) servlet thread safety issues

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.