??xml version="1.0" encoding="utf-8" standalone="yes"?>尤物视频网站在线观看,国产一区视频观看,日韩欧美亚洲v片http://www.aygfsteel.com/nikita/category/41654.htmlzh-cnFri, 11 Sep 2009 14:58:09 GMTFri, 11 Sep 2009 14:58:09 GMT60- 在Servlet/JSP中的几种变量cdhttp://www.aygfsteel.com/nikita/archive/2009/09/11/294784.htmlpicture talkpicture talkFri, 11 Sep 2009 12:30:00 GMThttp://www.aygfsteel.com/nikita/archive/2009/09/11/294784.htmlhttp://www.aygfsteel.com/nikita/comments/294784.htmlhttp://www.aygfsteel.com/nikita/archive/2009/09/11/294784.html#Feedback0http://www.aygfsteel.com/nikita/comments/commentRss/294784.htmlhttp://www.aygfsteel.com/nikita/services/trackbacks/294784.html源自 : http://www.javaresearch.org/article/8465.htm
一、在Servlet/JSP中的几种变量cd
在编写Servlet/JSPE序Ӟ对实例变量一定要心使用。因为实例变量是非线E安全的?br />在Servlet/JSP中,变量可以归ؓ下面的几c:
1. cd?br />requestQresponseQsessionQconfigQapplicationQ以及JSP面内置的page, pageContext?br />其中除了application外,其它都是U程安全的?br />
2. 实例变量
实例变量是实例所有的Q在堆中分配。在Servlet/JSP容器中,一般仅实例化一个Servlet/JSP实例Q?br />启动多个该实例的U程来处理请求。而实例变量是该实例所有的U程所׃nQ所以,实例变量不是U程安全的?br />
3. 局部变?br />局部变量在堆栈中分配,因ؓ每一个线E有自己的执行堆栈,所以,局部变量是U程安全的?br />
二、在Servlet/JSP中的多线E同步问?/h3>
在JSP中,使用实例变量要特别}慎。首先请看下面的代码Q?br />- // instanceconcurrenttest.jsp
- <%@ page contentType="text/html;charset=GBK" %>
- <%!
- //定义实例变量
- String username;
- String password;
- java.io.PrintWriter output;
- %>
- <%
- //从request中获取参?/font>
- username = request.getParameter("username");
- password = request.getParameter("password");
- output = response.getWriter();
- showUserInfo();
- %>
- <%!
- public void showUserInfo() {
- //ZH出q发问题Q在q儿首先执行一个费时操?/font>
- int i =0;
- double sum = 0.0;
- while (i++ < 200000000) {
- sum += i;
- }
-
- output.println(Thread.currentThread().getName() + "<br>");
- output.println("username:" + username + "<br>");
- output.println("password:" + password + "<br>");
- }
- %>
在这个页面中Q首先定义了两个实例变量Qusername和password。然后在从request中获取这两个参数Qƈ调用showUserInfo()Ҏ请求用L信息回显在该客户的浏览器上。在一个用戯问是Q不存在问题。但在多个用户ƈ发访问时Q就会出现其它用L信息昄在另外一些用L览器上的问题。这是一个严重的问题。ؓ了突出ƈ发问题,便于试、观察,我们在回昄户信息时执行了一个模拟的Ҏ操作Q比如,下面的两个用户同时访问(可以启动两个IE览器,或者在两台机器上同时访问)Q?br />aQ ?a href="http://localhost:8080/instanceconcurrenttest.jsp?username=a&password=123">http://localhost:8080/instanceconcurrenttest.jsp?username=a&password=123
bQ ?a href="http://localhost:8080/instanceconcurrenttest.jsp?username=b&password=456">http://localhost:8080/instanceconcurrenttest.jsp?username=b&password=456
如果a点击链接后,b再点击链接,那么Qa返回一个空白屏q,b则得到a以及b两个U程的输出。请看下面的屏幕截图Q?br />
?Qa的屏q?br />
?Qb的屏q?br />
从运行结果的截图上可以看刎ͼWeb服务器启动了两个U程分别来处理来自a和b的请求,但是在a却得C个空白的屏幕。这是因Z面程序中的output, username和password都是实例变量Q是所有线E共享的。在a讉K该页面后Q将output讄为a的输出,username,password分别|ؓa的信息,而在a执行printUserInfo()输出username和password信息前,b又访问了该页面,把username和password|ؓ了b的信息,q把输出output指向Cb。随后a的线E打印时Q就打印Cb的屏q了Qƈ且,a的用户名和密码也被b的取代。请参加下图所C:
?Qa、b两个U程的时间线
而实际程序中Q由于设|实例变量,使用实例变量q两个时间点非常接近Q所以,像本例的同步问题q没有这么突出,可能会偶出玎ͼ但这却更加具有危险性,也更加难于调试?br />
同样Q对于Servlet也存在实例变量的多线E问题,L上面面的Servlet版:
- // InstanceConcurrentTest.java
- import 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
- {
- //从request中获取参?/font>
- username = request.getParameter("username");
- password = request.getParameter("password");
- System.out.println(Thread.currentThread().getName() +
- " | set username:" + username);
- out = response.getWriter();
- showUserInfo();
- }
- public void showUserInfo() {
- //ZH出q发问题Q在q儿首先执行一个费时操?/font>
- 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);
- }
- }
三、解x?/h3>
1. 以单U程q行Servlet/JSP
在JSP中,通过讄Q?lt;%@ page isThreadSafe="false" %>Q在Servlet中,通过实现javax.servlet.SingleThreadModelQ此时Web容器保证JSP或Servlet实例以单U程方式q行?br />
重要提示Q在试中发玎ͼTomcat 4.1.17不能正确支持isThreadSafe属性,所以,指定isTheadSafe为false后,在Tomcat 4.1.17中仍然出现多U程问题Q这是Tomcat 4.1.17的Bug。在Tomcat 3.3.1和Resin 2.1.5中测试通过?/b>
2. 去除实例变量Q通过参数传?/h4>
从上面的分析可见Q应该在Servlet/JSP中尽量避免用实例变量。比如,下面的修正代码,去除了实例变量,通过定义局部变量,q参数进行传递。这P׃局部变量是在线E的堆栈中进行分配的Q所以是U程安全的。不会出现多U程同步的问题。代码如下:
- <%@ page contentType="text/html;charset=GBK" %>
- <%
- //使用局部变?/font>
- String username;
- String password;
- java.io.PrintWriter output;
- //从request中获取参?/font>
- 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) {
- //ZH出q发问题Q在q儿首先执行一个费时操?/font>
- int i =0;
- double sum = 0.0;
- while (i++ < 200000000) {
- sum += i;
- }
-
- _output.println(Thread.currentThread().getName() + "<br>");
- _output.println("username:" + _username + "<br>");
- _output.println("password:" + _password + "<br>");
- }
- %>
注:有的资料上指出在printUserInfo()Ҏ或者实例变量的相关操作语句上用synchronized关键字进行同步,但这样ƈ不能解决多线E的问题。因为,q样虽然可以使对实例变量的操作代码进行同步,但ƈ不能L一个线E用另外一个线E修改后的“脏的”实例变量。所以,除了降低q行效率外,不会起到预期效果?br />

]]>
վ֩ģ壺
|
۰|
¹|
|
|
|
|
ƽ|
ˮ|
|
|
ׯ|
ƽ|
̳|
˳|
Դ|
֣|
ȫ|
|
|
|
ԭ|
䶨|
|
绯|
ӯ|
ɽ|
|
ŷ|
|
|
̳|
|
ˮ|
|
|
ٺ|
̨ɽ|
|
|
|