Java Web review Part 6: Servlet thread security, javawebservlet

Source: Internet
Author: User

Java Web review Part 6: Servlet thread security, javawebservlet

I have mentioned a lot of basic Servlet knowledge before. This article focuses on Servlet thread security issues.

1: multi-threaded Servlet Model

To understand Servlet thread security, we must first understand how the Servlet instance is created and what its mode is.

By default, the Servlet container creates only one Servlet instance for the declared Servlet. If multiple clients request to access this Servlet at the same time, the Servlet container adopts multiple threads. Let's take a look at the figure below.

It can be seen that when the customer sends a request, the Servlet container selects a thread from the thread pool through the dispatcher thread, and then passes the request to the thread, then the Servlet Service method is executed in this thread.

If multiple clients request to execute a Servlet instance at the same time, the Service method of the Servlet container will be executed concurrently in multiple threads (CUSTOMER 1, Customer 2, when customer 3 calls the Servlet1 instance at the same time, the scheduler thread will call three threads in the thread pool for the customer's requests of 1, 2, and 3 respectively, then the three threads concurrently execute the Service method of the Servlet1 instance. Because the Servlet container adopts the multi-thread method of a single instance, the cost of creating the Servlet instance is greatly reduced, the response time to the request is improved, which also causes Servlet thread security problems. So let's talk about thread security.

2: Servlet thread Security 2.1: Variable Thread Security 2.1.1: Why does a variable have thread security?

Let's look at a piece of code first.

1 public class HelloWorldServlet extends HttpServlet {2 private String userName; 3 protected void doGet (HttpServletRequest request, HttpServletResponse response) throws IOException 4 {5 userName = request. getParameter ("userName"); 6 PrintWriter out = response. getWriter (); 7 if (userName! = Null & userName! = "") 8 {9 out. print (userName); 10} 11 else {12 out. println ("the user name does not exist"); 13} 14} 15}

Let's analyze this code. Now there are A and B2 clients simultaneously requesting the HelloWorldServlet instance, the Servlet container allocates thread T1 to serve the requests of Client A, and T2 to serve the requests of client B, the operating system first calls T1 to run the task. When T1 is run to line 1, the username is Zhang San and saved. At this time, the time segment is reached, the operating system starts to call T2. it also runs to line 2, but the user name is Li Si. Now the time segment is reached, and the operating system starts to run T1, however, at this time, the user name became Li Si, and the output was indeed Li Si (which is obviously incorrect). At this time, there was a thread security problem.

2.1.2: How to Prevent Variable Thread Security
  • Synchronize doGet with synchronized
  • Protected synchronized void doGet (HttpServletRequest request, HttpServletResponse response)

    This method is obviously not suitable, because T2 can be executed only after T1 is executed, greatly affecting the efficiency.

    3. If a static resource is added with final, the resource cannot be changed.

    Final static String url = "jdbc: mysql: // localhost: 3306/blog ";

    2.2: attribute thread security

    In Servlet, you can access the attributes stored in the ServletContext, HttpSession, and ServletRequest objects. These three objects provide the getAttribute () and setAttribute () methods for obtaining and setting attributes, so is the access to the attributes of these three objects in different ranges thread-Safe? Let's take a look at it.

    2.2.1: ServletContext

    First of all, it is clear that ServletContext is shared by all servlets in the application, so the ServletContext object can be accessed by all servlets in the web application, in this way, multiple servlets can set and access the attributes of ServletContext at the same time, So thread security problems may occur at this time. Let's look at a piece of code.

     1 protected void service(HttpServletRequest request, HttpServletResponse response) 2     { 3         String userName=request.getParameter("userName"); 4         if ("login") { 5             List list=(List)getServletContext().getAttribute("userList"); 6             list.add(userName); 7         } 8         else { 9             List list=(List)getServletContext().getAttribute("userList");10             list.remove(userName);11         }12     }
     1 protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException 2     { 3         List list=(List)getServletContext().getAttribute("userList"); 4         int count=list.size(); 5         for(int i=0;i<count;i++) 6         { 7             PrintWriter out=response.getWriter(); 8             out.println(list.get(i)); 9         }10     }

    The first code is to save the user name in the ServletContext attribute after the user logs on. If the user is not logged on, delete the user.

    The second code is to view the login status of all users in the application.

    When two requests are concurrently executed, the second part of the Code may obtain count = 5 when the fifth line is just executed; but the other request happens to execute the tenth line of the first line of code, A user is deleted. When the second segment of code runs to count = 5 during loop traversal, the array exceeds the limit. In this case, the thread security problem occurs. So how can we solve this problem? The first is to copy and save the value of ServletContext, and the second is to use synchronized for synchronization (this is inefficient)

    2.2.2: HttpSession

    HttpSession objects survive during user sessions and are not shared by all users like ServletContext. Therefore, an HttpSession requests only one user at the same time, therefore, in theory, Session is thread-safe, but this is not the case. This is related to the browser. In the previous Session, we said that the same browser can only have one Session, in this way, Session thread security issues will occur. See the following code:

    1 protected void service (HttpServletRequest request, HttpServletResponse response) throws IOException 2 {3 String commandType = request. getParameter ("commandType"); 4 HttpSession session = request. getSession (); 5 List list = (List) session. getAttribute ("items"); 6 if ("add ". equals (commandType) {7 // Add 8} 9 else if ("delete ". equals (commandType) {10 // Delete 11} 12 else {13 int count = list. size (); 14 for (int I = 0; I <count; I ++) {15 // traversing 16} 17} 18}

    The above is a simple pseudocode for adding item information, if a user deletes an item in a browser window and obtains all the items in another window, thread security occurs, from the above introduction, we know that the Servlet container is a multi-threaded single instance. At this time, the Servlet container will allocate two threads to serve the deletion and acquisition of all items respectively, if one of the threads runs until 14 rows of time segment ends, and the other thread runs 10th rows to delete an item information, then the first thread starts to run 15th again to start traversing, at this time, the above array is out of range.

    2.2.3: HttpRequest

    Httprequest is thread-safe, because each request calls the Service and creates a new HttpRequest that is the same as a local variable.

    3: SingleThreadModel

    It is a single-thread mode. That is to say, if the Servlet implements the SingleThreadModel interface, the Servlet container ensures that only one thread runs in the Service method of the Servlet instance at a time point (in fact, similar to synchronization) this affects efficiency. Now SingleThreadModel has been deprecated. It is worth noting that even if the Servlet implements the SingleThreadModel interface, thread security is not guaranteed. It is similar to ServletContext, HttpSession, because ServletContext is shared by applications, it is possible that two Servlet instances run simultaneously to cause thread security. HttpSession also appears because it is shared in the same browser (although unlikely)

    4: Conclusion

    1: as long as we understand the working mode of the Servlet container, we may be able to understand why the Servlet has thread security problems. Therefore, we must remember that the Servlet container is a model of multi-thread single instance.

    2: Avoid using global variables. It is best to use local variables. In fact, this is also a good programming habit.

    3: Read-only instance variables and static variables should be used (that is, the final variable must be added before)

    4: do not create a thread on the Servlet, because the Servlet container has already helped us.

    5: If you want to modify the shared object, remember to synchronize the object. Try to narrow down the synchronization scope (you can directly use synchronized (Session) when modifying the Session) to avoid performance impact.

     

    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.