<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 188,comments - 176,trackbacks - 0

     

    public class MyClass {
        
    private String variable1 ;
        
    private static String variable2 ;
        
    public MyClass(){   
        }

        
    public void method(){
            String variable3;
        }

     }



    上面是隨手寫的一個類,沒有任何意義,只是為了強調一些概念,這和這個主題很有關系:
    1) java中的變量的分類:
        a. 實例變量
        b. 局部變量
        c. 靜態變量
    本篇并不是java的基礎教程,因此不會詳盡到每個基礎知識點(下面的內容是區分對象和對象變量這兩個概念的,<<core java2>>嚴格區分,不過大多數教材并不過于苛刻的區別它們)
    a. 實例變量:屬于每個對象,也就是每個對象都有一份此變量的副本。上面的variable1就指向實例變量。
    b. 局部變量:工作在某個作用域,離開作用域之后成為垃圾。上面的variable3就指向局部變量,局部變量存在于方法中。
    c. 靜態變量:屬于某個類,也就是所有對象共有一個副本。上面的variable2就指向靜態變量。

    2) servlet容器的實例化:
    servlet如何被實例化的,不是我們所關心的,我們關心的是servlet被實例化了多少次,是每一次請求都實例化還是僅僅實例化一次?要解答這個問題太簡單了:

    public class Test extends HttpServlet {
        
    private static int count = 0;
        
    private int num = 0;
       
        
    public Test() {
            
    super();
            count 
    ++;
            System.out.println(
    "實例化了 "+count+" 次");
        }


        
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                
    throws ServletException, IOException {
            response.setContentType(
    "text/html");
            num 
    ++;
            System.out.println(
    "被訪問了" + num+"");
        }

    }



    打開瀏覽器,訪問指定的servlet,不斷點刷新,結果是:
    實例化了 1 次
    被訪問了1次
    被訪問了2次
    被訪問了3次

    不要關閉瀏覽器,再開一個瀏覽器訪問,不斷點刷新,結果是:
    被訪問了4次
    被訪問了5次
    被訪問了6次
    被訪問了7次
    被訪問了8次

    可見對不僅僅是對同一個用戶,對于其他用戶也只實例化一個對象。
    也就是說,Tomcat僅僅實例化一次servlet,產生一個對象。

    那servlet容器是如何相應多用戶同時訪問的呢?回答:多線程。為每次訪問都用一個獨立的線程運行doGet或者是doPost方法。也就是servlet容器的內部實現可能是這樣的:

    class extends Thread{
        
    public void run(){
           
    if(request 為 get)
               servlet.doGet();   
    // servlet指向你請求的servlet類的實例
           else if(request 為 post)
               servlet.doPost();
        }

    }



    這沒什么問題,但是一些初級程序員可能放這樣的錯誤:

    public class Test extends HttpServlet {
        
    private PrintWriter out ;

        
    public Test() {
            
    super();
        }


        
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                
    throws ServletException, IOException {
            response.setContentType(
    "text/html");
           out 
    = response.getWriter();
           out.println(request.getRemoteAddr());
        }

    }



    會有什么結果?單A訪問這個Test,通過response.getWriter()得到一個實例,保存在out中,假定這時候B在A之前執行完了response.getWriter(),并開始執行out.println(request.getRemoteAddr()),這時候out保存的并不是B自己通過getWriter()方法得到的PrintWriter對象,而是A運行getWriter的結果,那么B就輸出了A的地址。再看看下面的例子:

    建立一個webapp,名字叫做web,建立sendname.html的HTML文件,內容如下:

    <html>
      
    <head></head>
      
    <body>
            
    <form action="/web/Test">
                
    <input type="text" name="name"/>
                
    <input type="submit" />
            
    </form>
      
    </body>
    </html>



    建立一個servlet叫Test,內容如下:

    public class Test extends HttpServlet {
        
    private String name ;
        
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                
    throws ServletException, IOException {
            response.setContentType(
    "text/html");
            PrintWriter out 
    = response.getWriter();
            name 
    = request.getParameter("name");
            out.println(
    "I input "+name);
            
    try{Thread.sleep(5000);}catch(Exception ex){}
            out.println(
    "I am "+name);
            out.flush();
            out.close();
        }

    }



    通過瀏覽器打開2個sendname.html(http://localhost:8080/web/sendname.html),分別輸入名字A和B(間隔不要超過5秒):
    結果2個頁面顯示分別是:

    I input B I am B

    I input A I am B

    這就是Servlet中的多線程問題。解決的辦法很簡單,就是不用實例變量,至少不在絕對必要的時候用。
    在JSP中這樣的問題更加突出,因為使用<%!  %>進行的變量聲明得到的是一個實例變量,如果一定要定義,那么就使用synchronized,在使用實例變量的方法前加上synchronized,它也是不推薦使用的,下面是一個例子:

    <%@ page contentType="text/html;charset=GB2312" %>
    <HTML>
    <BODY>

        
    <!--number 為臨界區-->
        
    <%! int number=0;    
         
    synchronized void countPeople()
            
    { number++;
            }

        
    %>
        
    <% countPeople();
        
    %>
    <P><P>您是第
       
    <%=number%>
    個訪問本站的客戶。
    </BODY>
    </HTML>


     


    在<%! %>中定義的方式也會被多線程調用。
    對于JSP頁面,除了使用synchronized,還可以使用page指令元素的isThreadSafe來控制整個頁面是否可以多線程訪問。


    轉CSDN
    posted on 2007-05-24 11:23 cheng 閱讀(925) 評論(0)  編輯  收藏 所屬分類: JSP/Servlet
    主站蜘蛛池模板: 麻豆亚洲AV成人无码久久精品| 亚洲人成网站在线观看播放动漫 | 无码人妻丰满熟妇区免费| 亚洲精品动漫人成3d在线| 在线观看亚洲精品专区| 免费大学生国产在线观看p| 亚洲AV无码成人精品区日韩 | 99精品视频在线免费观看| 婷婷久久久亚洲欧洲日产国码AV| 免费看一区二区三区四区| 国产成A人亚洲精V品无码 | 在线观看视频免费完整版| 亚洲第一成人在线| 性xxxx视频播放免费| 在线观看亚洲免费| 亚洲理论电影在线观看| 久久久久国色av免费看| 亚洲综合免费视频| 成年大片免费视频| 日韩在线观看免费| 亚洲妇熟XXXX妇色黄| 亚洲美女免费视频| 久久精品国产亚洲av品善 | 久久精品亚洲精品国产色婷| 97在线观看永久免费视频| 久久亚洲精品国产亚洲老地址| 国产免费观看青青草原网站| 国产精品高清免费网站| 久久久久亚洲精品天堂| 国产一精品一AV一免费孕妇| 成人午夜影视全部免费看| 亚洲VA中文字幕无码毛片| 99在线精品视频观看免费| 美女18毛片免费视频| 亚洲av中文无码乱人伦在线r▽ | 在线免费播放一级毛片 | 久久亚洲sm情趣捆绑调教| 扒开双腿猛进入爽爽免费视频 | 亚洲精品无码久久| 国产成人综合亚洲AV第一页| 在线免费中文字幕|