js| Security | procedure
JSP default is multithreaded, this is the JSP and Asp,php,perl script language is not the same place, but also one of its advantages, but if you do not pay attention to the synchronization problem in multiple threads, will make the written JSP program has difficult to find errors. The following is an example of the multithreading problem in JSP and how to solve it.
One, JSP in the existence of multithreading problems:
When a client requests a JSP file for the first time, the server compiles the JSP into a class file, creates an instance of the class, and then creates a thread to handle the client-side request. If more than one client requests the JSP file at the same time, the server creates multiple threads. Each client request corresponds to a thread. Implementing multithreading can greatly reduce the resource requirements of the system and increase the concurrency and response time of the system. The variables that might be used in a JSP are described below:
- Instance variables
Instance variables are allocated in the heap and are shared by all threads belonging to that instance, so they are not thread-safe.
- 8 class variables provided by JSP system
OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT used in JSP are thread-safe, application are used throughout the system and are not thread-safe.
- Local variables
Local variables are allocated on the stack, because each thread has its own stack space, so it is thread-safe.
- Static class
Static classes can be used directly, and are not thread-safe, without being instantiated.
- External resources:
There may be multiple threads or processes in your program that simultaneously manipulate the same resource (for example, multiple threads or processes writing to a file at the same time). Be aware of synchronization issues at this point.
Second, the following examples of multithreading problems:
<%@ page import= "
javax.naming.*,
Java.util.*,
Java.sql.*,
weblogic.common.*
"%>
<%
String Name
String product;
Long quantity;
Name=request.getparameter ("name");
Product=request.getparameter ("Product");
Quantity=request.getparameter ("Quantity"); /* (1) * *
Savebuy ();
%>
<%!
public void Savebuy ()
{
/* Perform database operations, save data to the table * *
try {
Properties Props = new properties ();
Props.put ("User", "Scott");
Props.put ("Password", "Tiger");
Props.put ("Server", "DEMO");
Driver mydriver = (Driver) Iver "). newinstance ();
conn = Mydriver.connect ("jdbc:weblogic:oracle", props);
stmt = Conn.createstatement ();
String inssql = "INSERT into buy (empid, name, dept) VALUES (?,?,?,?)";
stmt = Conn.preparestatement (Inssql);
Stmt.setstring (1, name);
Stmt.setstring (2, procuct);
Stmt.setint (3, quantity);
Stmt.execute ();
}
catch (Exception e)
{
System.out.println ("SQLException was thrown:" + e.getmessage ());
}
Finally//close connections and {
try {
if (stmt!= null)
Stmt.close ();
IF (conn!= null)
Conn.close ();
catch (SQLException Sqle) {
System.out.println ("SQLException was thrown:" + sqle.getmessage ());
}
}
}
%>
The above program simulates a part of online shopping and saves the user name, the name of the item purchased, and the number of items you enter in the browser to the table. An instance variable is used in the Savebuy () function, so it is not thread safe. Because: every statement in a program is not an atomic operation, such as Name=request.getparameter ("name"); in execution it corresponds to multiple machine instructions. Can be switched to sleep at any time due to system scheduling let the other thread continue. If thread a goes to sleep when it executes to (1), thread B begins to execute and changes the value of the quantity, then when it executes, it starts executing from the call Savebuy () function, So that the quantity that it saves to the table is a value that is changed by thread B, the number of users that thread a corresponds to actually buys is inconsistent with the data persisted in the table. This is a very serious problem.
Third, the solution
- Using single thread
In the JSP file, add: <%@ page isthreadsafe= "false"%>, so that it executes in a single thread, when there is still only one instance, all client requests are executed serially. This can degrade the performance of the system.
- Thread Synchronization of Function savebuy () plus synchronized, which is still performed in multithreading, but can also degrade system performance
Public synchronized void Savebuy ()
{
......
}
- Using local variables instead of instance variables, the function savebuy () is declared as follows:
Because the parameters that are passed to him in Savebuy () are allocated in the stack, they are thread-safe.
public void Savebuy (String name,string product, int quantity)
{
......
}
The method of invocation should read:
<%
String Name
String product;
Long quantity;Name=request.getparameter ("name");
Product=request.getparameter ("Product");
Quantity=request.getparameter ("Quantity");
Savebuy (name,product,quantity)
%>
If you have a lot of savebuy parameters, or if the data is used in many places, you can declare a class and use it as a parameter, such as:
public class Buyinfo
{
String name;
String product;
Long quantity;
}public void Savebuy (Buyinfo info)
{
......
}
The method of invocation should read:
<%
Buyinfo userbuy = new Buyinfo ();
Userbuy.name=request.getparameter ("name");
Userbuy.product=request.getparameter ("Product");
Userbuy.quantity=request.getparameter ("Quantity");
Savebuy (userbuy);
%>
So it's best to use 3 because 1,2 can degrade the performance of the system.
Multithreading problems are generally only possible in the case of large concurrent volume access, and are difficult to repeat, so you should always be aware of programming.