JSP thread safety

First, the concept

JSP and other scripting languages, JSP default mode is multi-threaded execution, there may be multiple users to simultaneously read a variable of the problem in the implementation.

First look at the relationship between class variables, instance variables, local variables.

1. class variable
request, response, session, config, application, and JSP pages built-in page, pageContext.
Which in addition to application, the other are thread safe.

2. instance variables
instance variables are all examples of allocation on the heap. In Servlet / JSP container, generally only instantiates a Servlet / JSP instance,
start threads of the plurality of instances to process the request. The instance variables are all the threads share the instance, the instance variables are 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.

 

Instance variables and methods defined in the local variables of JSP:

Variables and methods within the <%!%> Are variables and methods in a class that is member variables and member methods.

Variables in <%%> is a process variable which is a local variable.

Second, the problem

Look at the following code

 

<!%  
     @ Define instance variables   
    String username;   
    String password;   
    java.io.PrintWriter Output;  
 %>   
<%   @ acquisition parameters from the request   
    username = request.getParameter ( "username" );   
    password = request.getParameter ( " password " );   
    Output = response.getWriter ();   
    showUserInfo ();       %>   
! <%   public void showUserInfo () {  
         // to highlight the concurrency problem, here first performs a time-consuming operation int I = 0, J = 0, = 0 K ;  
         Double SUM = 0.0 ;  
         the while
    

     
         (i++ < 999999999) {
            while(j++<999999999){
                while(k++ < 999999999){
                    sum += i; 
                }
            }
        }  
        output.println(Thread.currentThread().getName() + "<br>");  //获取当前进程的名称
        output.println("username:" + username + "<br>");  
        output.println("password:" + password + "<br>");  
    }  
%>  

 

In this page, we first define the two instance variables, username and password. Then get the two parameters from the request and calls showUserInfo () method to request user information echo on the customer's browser. When a user visits, the problem does not exist. However, when multiple users concurrent access, there will be other user's information display problems on some other user's browser. This is a serious problem. In order to highlight concurrency issues, ease of testing, observation, we performed a time-consuming operation when the echo of the simulated user information, for example, the following two users simultaneously (IE browser can be started simultaneously access two):

http://localhost:8080/3/1.jsp?username=a&password=123
http://localhost:8080/3/1.jsp?username=b&password=456

If you click on the link after a, b and then click on the link, then, would a return to a blank screen, you get the output b a and b are two threads:

 

This is because the above program output, username and password are the instance variables are shared by all threads. After a visit to the page, the output is set to the output of a, username, password are set information a, is performed printUserInfo in a () before outputting the username and password information, b has visited the page, the username and password to set the information b, and outputs to the output point b. Followed by a thread when printing, print to screen a b, and, a user name and password has also been replaced b.

The actual interval time must be very short two operations, this problem may occur when a large number of visits.

Third, the solution

1. Remove the instance variables, parameters passed by

code show as below

 

<%  
    //使用局部变量  
    String username;  
    String password;  
    java.io.PrintWriter output;  
    //从request中获取参数  
    username = 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) {  
        //为了突出并发问题,在这儿首先执行一个费时操作  
       int i =0,j=0,k=0;  
        double sum = 0.0;  
        while (i++ < 999999999) {
            while(j++<999999999){
                while(k++ < 999999999){
                    sum += i; 
                }
            }   
        }  
        _output.println(Thread.currentThread().getName() + "<br>");  
        _output.println("username:" + _username + "<br>");  
        _output.println("password:" + _password + "<br>");  
    }  
%>  

 

运行结果如下:

通过定义局部变量,并参数进行传递。这样,由于局部变量是在线程的堆栈中进行分配的,所以是线程安全的。不会出现多线程同步的问题

 

 

2.以单线程方式运行

JSP界面设置如下

 

<%@page isThreadSafe="false"%> 

 

默认为true,是多线程模式

如果将JSP或Servlet设置成单线程工作模式,会导致每个请求创建一个Servlet实例,这种实践将导致严重的性能问题(服务器的内存压力很大,还会导致频繁的垃圾回收),所以通常情况下并不会这么做。

 

 

参考:

https://www.iteye.com/blog/ajax-xu-1140665

https://blog.csdn.net/chunyufeiyun/article/details/11786605

Guess you like

Origin www.cnblogs.com/adhzl/p/12041056.html