Multi-thread synchronization in Servlet and JSP _ MySQL

Source: Internet
Author: User
Compared with ASP and PHP, ServletJSP has a high execution efficiency due to its multi-threaded operation. Because ServletJSP is executed in multi-thread mode by default, you need to carefully consider the multi-thread synchronization issue when writing code. However, many developers did not notice the problem of multi-thread synchronization when writing the ServletJSP program, which often caused the programming servlet

   Compared with ASP and PHP, Servlet/JSP has a high execution efficiency due to its multi-threaded operation. Servlet/JSP is executed in multi-thread mode by default. Therefore, you must carefully consider the multi-thread synchronization issue when writing code. However, many developers did not notice the problem of multi-thread synchronization when writing Servlet/JSP programs, which often caused no problems when a few users access the program, when concurrent users reach a certain value, some unknown problems often occur, and debugging is difficult for such random problems.

  I. variable types in Servlet/JSP

When writing Servlet/JSP programs, be careful when using instance variables. Because instance variables are non-thread-safe. In Servlet/JSP, variables can be classified into the following categories:

  1. class variables

Request, response, session, config, application, and built-in pages and pageContext of JSP pages. All applications are thread-safe.

  2. instance variables

Instance variables are owned by instances and allocated in the heap. In Servlet/JSP containers, only one Servlet/JSP instance is instantiated, and multiple threads of the instance are started to process requests. Instance variables are shared by all threads of the instance. Therefore, instance variables are not thread-safe.

  3. local variables

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

  II. multi-thread synchronization in Servlet/JSP

In JSP, be cautious when using instance variables. First, see the following code:

     
      
// Instanceconcurrenttest. jsp <% @ page contentType = "text/html; charset = GBK" %> <%! // Define the instance variable String username; String password; java. io. printWriter output; %> <% // Obtain the parameter username = request from the request. getParameter ("username"); password = request. getParameter ("password"); output = response. getWriter (); showUserInfo (); %> <%! Public void showUserInfo () {// to highlight the concurrency problem, run a time-consuming operation int I = 0; double sum = 0.0; while (I ++ <200000000) {sum + = I;} output. println (Thread. currentThread (). getName () +"
      
"); Output. println (" username: "+ username +"
"); Output. println (" password: "+ password +"
") ;}%>


On this page, we first define two instance variables: username and password. Then obtain the two parameters from the request and call the showUserInfo () method to display the information of the requesting user in the client's browser. There is no problem during a user access. However, when multiple users access the service concurrently, the information of other users is displayed on the browsers of other users. This is a serious problem. To highlight concurrency issues and facilitate testing and observation, we performed a simulated time-consuming operation when returning the user information. for example, the following two users can simultaneously access the site (two IE browsers can be started, or access the service on both machines at the same time ):

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

B: http: // localhost: 8080/instanceconcurrenttest. jsp? Username = B & password = 456

If a clicks the link and B clicks the link again, a returns a blank screen, and B gets the output of both threads a and B. See the following screen:



: A screen



: B screen

The running result shows that the Web server starts two threads to process requests from a and B respectively, but a Gets a blank screen in. This is because the output, username, and password in the above program are both instance variables and are shared by all threads. After a accesses this page, it sets output to a's output, username, and password to a's information respectively. before a executes printUserInfo () to output username and password information, B visited the page again, set username and password to B, and point the output to B. When the thread of a is printed, it is printed to the screen of B, and the user name and password of a are also replaced by B. See:



: Timeline of two threads a and B

In the actual program, because the instance variables are set, the two time points of the instance variables are very close, so the synchronization problem in this example is not so prominent and may occasionally occur, however, this is more dangerous and difficult to debug.

Similarly, the Servlet also has the multi-thread problem of instance variables. please refer to the Servlet version on 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 {// Obtain the parameter username = request from the 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 concurrency issues, 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 );}}
      


   III. solutions

   1. run Servlet/JSP in a single thread

In JSP, set <% @ page isThreadSafe = "false" %> to implement javax in Servlet. servlet. singleThreadModel. at this time, the Web container ensures that JSP or Servlet instances run in a single thread mode.

Note: During the test, we found that Tomcat 4.1.17 does not correctly support the isThreadSafe attribute. Therefore, after you set isTheadSafe to false, multithreading still occurs in Tomcat 4.1.17, which is a Bug in Tomcat 4.1.17. The test passed in Tomcat 3.3.1 and Resin 2.1.5.

   2. remove instance variables and pass parameters

From the above analysis, we can avoid using instance variables in Servlet/JSP. For example, the following correction code removes instance variables, defines local variables, and transmits parameters. In this way, because local variables are allocated in the thread stack, it is thread-safe. No multi-thread synchronization issues. The code is as follows:

      
       
<% @ Page contentType = "text/html; charset = GBK" %> <% // use the local variable String username; String password; java. io. printWriter output; // Obtain the parameter username = request from the request. getParameter ("username"); 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 issues, execute a time-consuming operation int I = 0; double sum = 0.0; while (I ++ <200000000) {sum + = I;} _ output. println (Thread. currentThread (). getName () +"
       
"); _ Output. println (" username: "+ _ username +"
"); _ Output. println (" password: "+ _ password +"
") ;}%>


Note: Some documents indicate that synchronized keywords are used for synchronization in the printUserInfo () method or related operation statements of instance variables, but this does not solve the problem of multithreading. Because, although the operation code of instance variables can be synchronized, it does not prevent a thread from using the "dirty" instance variable modified by another thread. Therefore, in addition to reducing the operating efficiency, it will not achieve the expected results.

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.