Multithreading synchronization problems in Servlet and JSP

Source: Internet
Author: User
Tags define execution variables variable thread tomcat
Js|servlet| Multithreading | problem


Compared with ASP and PHP, servlet/jsp technology has high execution efficiency because of its multithreading operation. Because servlet/jsp is performed in multithreaded mode by default, multithreading synchronization issues need to be considered very carefully when writing code. However, many people write servlet/jsp programs and do not notice the problem of multithreading synchronization, this often causes the program to write in a small number of user access without any problems, and in the concurrent user rise to a certain value, will often appear some problems, for such a random problem debugging is very difficult.

  I. Several variable types in servlet/jsp

When writing a servlet/jsp program, be careful with the instance variables. Because the instance variable is not thread safe. In servlet/jsp, variables can be grouped into the following categories:

  1. Class variables

Request,response,session,config,application, as well as JSP pages built into page, PageContext. In addition to application, the other is thread-safe.

  2. Instance Variables

Instance variables are instances of all, allocated in the heap. In the servlet/jsp container, you typically instantiate only one servlet/jsp instance and start multiple threads of that instance to handle the request. The instance variable is shared by all threads of the instance, so the instance variable is not thread safe.

  3. Local Variables

Local variables are allocated on the stack because each thread has its own execution stack, so local variables are thread safe.

  Second, the multithreading synchronization problem in the servlet/jsp

In the JSP, use instance variables with particular caution. First, look at the following code:

FFFFFF cellpadding=2 width=540 align=center bordercolorlight=black border=1>

 
  
   
  instanceconcurrenttest.jsp<%@ page contenttype= "TEXT/HTML;CHARSET=GBK"%><%!     Define instance variable     String username;     String password;    Java.io.PrintWriter output;%><%     //Get parameters from request    username = Request.getparameter ("username");    Password = request.getparameter ("password");    Output = Response.getwriter ();    Showuserinfo ();  %> <%!     public void Showuserinfo () {         //to highlight the concurrency problem, a time-consuming operation of         int i =0 is first performed here;         Double sum = 0.0;         while (i++ < 200000000) {             sum = i;         }                  Output.println (Thread.CurrentThread (). GetName () + "<br>");       Output.println ("Username:" + username + "<br>");        Output.println ("Password:" + password + "<br>");     } %>
 
  


In this page, you first define two instance variables, username and password. The two parameters are then fetched from the request and the Showuserinfo () method is invoked to echo the requested user's information back to the client's browser. In a user access Yes, there is no problem. However, when multiple users have concurrent access, there is a problem with other users ' information appearing on other users ' browsers. This is a serious problem. To highlight concurrency issues, to facilitate testing and observation, we performed a simulated time-consuming operation when echoing user information, for example, the following two users (can start two IE browsers, or on two machines simultaneously access):

A:http://localhost:8080/instanceconcurrenttest.jsp?username=a&password=123

b:http://localhost:8080/instanceconcurrenttest.jsp?username=b&password=456

If a clicks on the link, b then clicks on the link, then a will return a blank screen, and B gets the output of A and b two threads. Take a look at the screenshot below:



Figure 1:a's screen



Figure 2:b's screen

As you can see from the screenshot of the run results, the Web server started two threads to process requests from A and B, but a blank screen was found in a. This is because output in the above program, username and password are instance variables that are shared by all threads. After a accesses the page, the output is set to a, username,password the information of a, and before a executes printuserinfo () outputs username and password information, b accesses the page, The username and password are placed for the information of B, and the output is pointed to B. Then A's thread prints to the B screen, and A's username and password are replaced by B. Please take part in the following figure:



Figure 3:a, b two-thread timeline

But in the actual program, because set instance variable, use instance variable these two time points very close, so, like this example synchronization problem is not so prominent, may occasionally appear, but this is more dangerous, and more difficult to debug.

Similarly, for servlet problems with instance variables, see the servlet version of the above page:

  
   
Instanceconcurrenttest.javaimport Javax.servlet.*;import Javax.servlet.http.*;import Java.io.PrintWriter;public       Class Instanceconcurrenttest extends HttpServlet {String username;       String password;       PrintWriter out; public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception    , java.io.IOException {//Get parameters from request Username = Request.getparameter ("username");     Password = request.getparameter ("password"); System.out.println (Thread.CurrentThread (). GetName () + "|    Set Username: "+ username);     out = Response.getwriter ();         Showuserinfo ();      public void Showuserinfo () {//To highlight the concurrency problem, first execute a time-consuming operation int i = 0;      Double sum = 0.0;      while (i++ < 200000000) {sum = i;    } out.println ("Thread:" + thread.currentthread (). GetName ());     Out.println ("Username:" + username);  Out.println ("Password:" + password); }}
  


   Third, the solution

   1. Run servlet/jsp with single thread

In the JSP, by setting: <%@ page isthreadsafe= "false"%&gt, in the servlet, By implementing Javax.servlet.SingleThreadModel, the Web container will ensure that the JSP or servlet instance is running in a single-threaded manner.

Important: The test found that Tomcat 4.1.17 did not correctly support the IsThreadSafe property, so when you specify Istheadsafe as false, there are still multithreading problems in Tomcat 4.1.17, which is Tomcat A 4.1.17 bug. Tested through in Tomcat 3.3.1 and resin 2.1.5.

   2. Remove the instance variable, pass through the parameter

As you can see from the above analysis, you should try to avoid using instance variables in servlet/jsp. For example, the following correction code eliminates the instance variables by defining local variables and passing parameters. In this way, the local variables are thread-safe because they are allocated in the thread's stack. There is no problem with multithreading synchronization. The code is as follows:

 
    
     
  <%@ page contenttype= "TEXT/HTML;CHARSET=GBK"%><%     //using local variable    String username;    String password;    Java.io.PrintWriter output;    Get the parameter    username = request.getparameter ("username") from request;    Password = request.getparameter ("password");    Output = Response.getwriter ();    Showuserinfo (output, username, password);%><%!     public void Showuserinfo (Java.io.PrintWriter _output,     string _username, String _password) {    //To highlight concurrency problems, Here first executes a time-consuming operation      int i =0;       Double sum = 0.0;       while (i++ < 200000000) {         sum = i;        }          _output.println (Thread.CurrentThread (). GetName () + "<br>");      _output.println ("Username:" + _username + "<br>");      _output.println ("Password:" + _password + "<br>");      } %>
 
    


Note: Some data indicate that the Synchronized keyword is used to synchronize the Printuserinfo () method or the relevant operation statements of instance variables, but this does not solve the problem of multithreading. This is because, while synchronizing the operation code of an instance variable, it does not prevent one thread from using another thread's modified "dirty" instance variable. Therefore, in addition to reducing operational efficiency, will not play the desired effect.




Related Article

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.