JSP is executed in multiple threads by default. This is different from ASP, PHP, Perl, and other scripting languages. It is also one of its advantages. However, if you do not pay attention to the synchronization problem in multiple threads, this will make the JSP program hard to discover errors. The following is an example of multithreading in JSP and its solution.
I. multithreading in JSP:
When the client requests a JSP file for the first time, the server compiles the JSP file into a class file, creates an instance of this class, and then creates a thread to process client requests. If multiple clients request the JSP file at the same time, the server creates multiple threads. Each client request corresponds to a thread. Multi-threaded execution can greatly reduce system resource requirements and increase the concurrency and response time of the system. The possible variables in JSP are described as follows:
- Instance variables
Instance variables are allocated in the heap and shared by all the threads of the instance, so they are not thread-safe.
- Eight class variables provided by the JSP system
The out, request, response, session, config, page, and pageconxt used in JSP are thread-safe and application is used throughout the system, so they are not thread-safe.
- Local variable
Local variables are allocated in the stack. Because each thread has its own stack space, it is thread-safe.
- Static class
Static classes can be directly used without being instantiated, and are not thread-safe.
- External resources:
In a program, multiple threads or processes may simultaneously operate on the same resource (for example, multiple threads or processes simultaneously perform write operations on a file). At this time, pay attention to the synchronization problem.
Ii. multithreading in the following example:
<% @ 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 and save the 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.exe cute ();
}
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, purchased item name, and quantity entered by the user in the browser to the table buy. Instance variables are used in the savebuy () function, so it is not thread-safe. because: each statement in the program is not an atomic operation, such as name = request. getparameter ("name"); multiple machine commands are generated during execution, and may be transferred to sleep due to system scheduling at any time, so that other threads can continue to execute. if thread a is in sleep state when it is executed to (1), thread B starts to execute and changes the value of quantity. When it is executed to thread a again, it will call savebuy () the function is executed, so that the quantity saved to the table is the value modified by thread B. Then, the actual number of users purchased by thread a is inconsistent with the data in the table. this is a serious problem.
Iii. Solution
- Single-threaded
Add the following to the JSP file: So that it is executed in a single thread. At this time, there is still only one instance, and all client requests are executed in a serial way. This will reduce the system performance.
- The savebuy () function is added with synchronized for thread synchronization. the JSP is still executed in multiple threads, but it also reduces the system performance.
Public synchronized void savebuy ()
{
......
}
- Use local variables instead of instance variables. The savebuy () function is declared as follows:
Because savebuy () uses the passed parameter and is allocated in the stack, It is thread-safe.
Public void savebuy (string name, string product, int quantity)
{
......
}The call method is changed:
<%
String name
String product;
Long quantity;
Name = request. getparameter ("name ");
Product = request. getparameter ("product ");
Quantity = request. getparameter ("quantity ");
Savebuy (name, product, quantity)
%>
If savebuy has many parameters or the data needs to be used in many places, you can declare a class and use it as a parameter, for example:
Public class buyinfo
{
String name;
String product;
Long quantity;
}
Public void savebuy (buyinfo info)
{
......
}
The call method is changed:
<%
Buyinfo userbuy = new buyinfo ();
Userbuy. Name = request. getparameter ("name ");
Userbuy. Product = request. getparameter ("product ");
Userbuy. Quantity = request. getparameter ("quantity ");
Savebuy (userbuy );
%>
So it is best to use 3, because 1 and 2 will reduce the system performance.
Multithreading is generally possible only when there is a large amount of concurrent access, and it is difficult to repeat, so you should always pay attention to it during programming.
Author Profile |
|
Dev2dev ID: xcjing, Bea senior technical consultant, has been in BEA China for many years and has rich experience in portal technology and RFID solutions. |