<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;
        }

     }



    上面是隨手寫(xiě)的一個(gè)類(lèi),沒(méi)有任何意義,只是為了強(qiáng)調(diào)一些概念,這和這個(gè)主題很有關(guān)系:
    1) java中的變量的分類(lèi):
        a. 實(shí)例變量
        b. 局部變量
        c. 靜態(tài)變量
    本篇并不是java的基礎(chǔ)教程,因此不會(huì)詳盡到每個(gè)基礎(chǔ)知識(shí)點(diǎn)(下面的內(nèi)容是區(qū)分對(duì)象和對(duì)象變量這兩個(gè)概念的,<<core java2>>嚴(yán)格區(qū)分,不過(guò)大多數(shù)教材并不過(guò)于苛刻的區(qū)別它們)
    a. 實(shí)例變量:屬于每個(gè)對(duì)象,也就是每個(gè)對(duì)象都有一份此變量的副本。上面的variable1就指向?qū)嵗兞俊?br /> b. 局部變量:工作在某個(gè)作用域,離開(kāi)作用域之后成為垃圾。上面的variable3就指向局部變量,局部變量存在于方法中。
    c. 靜態(tài)變量:屬于某個(gè)類(lèi),也就是所有對(duì)象共有一個(gè)副本。上面的variable2就指向靜態(tài)變量。

    2) servlet容器的實(shí)例化:
    servlet如何被實(shí)例化的,不是我們所關(guān)心的,我們關(guān)心的是servlet被實(shí)例化了多少次,是每一次請(qǐng)求都實(shí)例化還是僅僅實(shí)例化一次?要解答這個(gè)問(wèn)題太簡(jiǎn)單了:

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


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

    }



    打開(kāi)瀏覽器,訪問(wèn)指定的servlet,不斷點(diǎn)刷新,結(jié)果是:
    實(shí)例化了 1 次
    被訪問(wèn)了1次
    被訪問(wèn)了2次
    被訪問(wèn)了3次

    不要關(guān)閉瀏覽器,再開(kāi)一個(gè)瀏覽器訪問(wèn),不斷點(diǎn)刷新,結(jié)果是:
    被訪問(wèn)了4次
    被訪問(wèn)了5次
    被訪問(wèn)了6次
    被訪問(wèn)了7次
    被訪問(wèn)了8次

    可見(jiàn)對(duì)不僅僅是對(duì)同一個(gè)用戶,對(duì)于其他用戶也只實(shí)例化一個(gè)對(duì)象。
    也就是說(shuō),Tomcat僅僅實(shí)例化一次servlet,產(chǎn)生一個(gè)對(duì)象。

    那servlet容器是如何相應(yīng)多用戶同時(shí)訪問(wèn)的呢?回答:多線程。為每次訪問(wèn)都用一個(gè)獨(dú)立的線程運(yùn)行doGet或者是doPost方法。也就是servlet容器的內(nèi)部實(shí)現(xiàn)可能是這樣的:

    class extends Thread{
        
    public void run(){
           
    if(request 為 get)
               servlet.doGet();   
    // servlet指向你請(qǐng)求的servlet類(lèi)的實(shí)例
           else if(request 為 post)
               servlet.doPost();
        }

    }



    這沒(méi)什么問(wèn)題,但是一些初級(jí)程序員可能放這樣的錯(cuò)誤:

    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());
        }

    }



    會(huì)有什么結(jié)果?單A訪問(wèn)這個(gè)Test,通過(guò)response.getWriter()得到一個(gè)實(shí)例,保存在out中,假定這時(shí)候B在A之前執(zhí)行完了response.getWriter(),并開(kāi)始執(zhí)行out.println(request.getRemoteAddr()),這時(shí)候out保存的并不是B自己通過(guò)getWriter()方法得到的PrintWriter對(duì)象,而是A運(yùn)行g(shù)etWriter的結(jié)果,那么B就輸出了A的地址。再看看下面的例子:

    建立一個(gè)webapp,名字叫做web,建立sendname.html的HTML文件,內(nèi)容如下:

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



    建立一個(gè)servlet叫Test,內(nèi)容如下:

    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();
        }

    }



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

    I input B I am B

    I input A I am B

    這就是Servlet中的多線程問(wèn)題。解決的辦法很簡(jiǎn)單,就是不用實(shí)例變量,至少不在絕對(duì)必要的時(shí)候用。
    在JSP中這樣的問(wèn)題更加突出,因?yàn)槭褂?lt;%!  %>進(jìn)行的變量聲明得到的是一個(gè)實(shí)例變量,如果一定要定義,那么就使用synchronized,在使用實(shí)例變量的方法前加上synchronized,它也是不推薦使用的,下面是一個(gè)例子:

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

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

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


     


    在<%! %>中定義的方式也會(huì)被多線程調(diào)用。
    對(duì)于JSP頁(yè)面,除了使用synchronized,還可以使用page指令元素的isThreadSafe來(lái)控制整個(gè)頁(yè)面是否可以多線程訪問(wèn)。


    轉(zhuǎn)CSDN
    posted on 2007-05-24 11:23 cheng 閱讀(925) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): JSP/Servlet
    主站蜘蛛池模板: 亚洲精品日韩一区二区小说| 激情五月亚洲色图| 亚洲伊人tv综合网色| 亚洲大尺码专区影院| 亚洲乱亚洲乱妇24p| 无码的免费不卡毛片视频| 国产在线精品观看免费观看| 精品一区二区三区免费毛片爱| 无码国产精品久久一区免费| 四虎AV永久在线精品免费观看| 亚洲精品二区国产综合野狼 | 亚洲精品无码久久毛片| 亚洲高清国产AV拍精品青青草原| 亚洲激情黄色小说| 黄色毛片免费网站| 老汉精品免费AV在线播放| 日韩电影免费在线| 亚洲另类激情综合偷自拍图| 亚洲人成电影院在线观看| 美女裸免费观看网站| 91福利视频免费观看| 在线免费观看韩国a视频| 亚洲αv久久久噜噜噜噜噜| 一区二区亚洲精品精华液| 在线观看免费黄色网址| 成人免费视频试看120秒| 亚洲一区爱区精品无码| ASS亚洲熟妇毛茸茸PICS| 国产99久久久国产精免费| 美女被免费喷白浆视频| 青青草原亚洲视频| 亚洲人成77777在线播放网站不卡 亚洲人成77777在线观看网 | 免费a级毛片无码a∨性按摩| 亚洲AV美女一区二区三区| 久久久久亚洲国产AV麻豆| 亚洲一区二区在线免费观看| 国产精品成人无码免费| 亚洲精品一区二区三区四区乱码| 特级毛片全部免费播放a一级| 91精品免费久久久久久久久| 亚洲自偷自偷图片|