<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

     

    JSP默認(rèn)是以多線程方式執(zhí)行的,這是JSP與ASP,PHP,PERL等腳本語言不一樣的地方,也是它的優(yōu)勢之一,但如果不注意多線程中的同步問題,會使所寫的JSP程序有難以發(fā)現(xiàn)的錯誤。下面以一個例子說明JSP中的多線程問題及解決方法。

     

    一、JSP的中存在的多線程問題:

    當(dāng)客戶端第一次請求某一個JSP文件時,服務(wù)端把該JSP編譯成一個CLASS文件,并創(chuàng)建一個該類的實例,然后創(chuàng)建一個線程處理CLIENT端的請求。如果有多個客戶端同時請求該JSP文件,則服務(wù)端會創(chuàng)建多個線程。每個客戶端請求對應(yīng)一個線程。以多線程方式執(zhí)行可大大降低對系統(tǒng)的資源需求,提高系統(tǒng)的并發(fā)量及響應(yīng)時間.對JSP中可能用的的變量說明如下:

    實例變量


    實例變量是在堆中分配的,并被屬于該實例的所有線程共享,所以不是線程安全的.


    JSP系統(tǒng)提供的8個類變量


    JSP中用到的OUT,Request,Response,Session,Config,Page,PageConxt是線程安全的,Application在整個系統(tǒng)內(nèi)被使用,所以不是線程安全的.


    局部變量


    局部變量在堆棧中分配,因為每個線程都有它自己的堆棧空間,所以是線程安全的.


    靜態(tài)類


    靜態(tài)類不用被實例化,就可直接使用,也不是線程安全的.


    外部資源:


    在程序中可能會有多個線程或進(jìn)程同時操作同一個資源(如:多個線程或進(jìn)程同時對一個文件進(jìn)行寫操作).此時也要注意同步問題.

    二、下面的例子存在的多線程問題:

    <%@ page import="
    javax.naming.*,
    java.util.*,
    java.sql.*,
    weblogic.common.*
    " %>

    <%@ 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() 

    /*進(jìn)行數(shù)據(jù)庫操作,把數(shù)據(jù)保存到表中*/ 
    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()); 
    }
     
    }
     

    %> 

    <%!
    public void  savebuy()
    {
        /*進(jìn)行數(shù)據(jù)庫操作,把數(shù)據(jù)保存到表中*/
        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());
            }
        }
    }
    %>

    上面的程序模擬網(wǎng)上購物中的一部分,把用戶在瀏覽器中輸入的用戶名,購買的物品名稱,數(shù)量保存到表BUY中。在savebuy()函數(shù)中用到了實例變量,所以它不是線程安全的.因為:程序中的每一條語句都不是原子操作,如name=request.getParameter("name");在執(zhí)行是會對應(yīng)多個機器指令,在任何時候都可能因系統(tǒng)調(diào)度而轉(zhuǎn)入睡眠狀態(tài),讓其他的線程繼續(xù)執(zhí)行.如果線程A在執(zhí)行到(1)的時候轉(zhuǎn)入睡眠狀態(tài),線程B開始執(zhí)行并改變QUANTITY的值,那么當(dāng)又到A執(zhí)行時,它會從調(diào)用savebuy()函數(shù)開始執(zhí)行,這樣它保存到表中的QUANTITY是被線程B改過的值,那么線程A對應(yīng)的用戶所實際購買的數(shù)量與保持到表中的數(shù)據(jù)不一致.這是個很嚴(yán)重的問題.

    三、解決方法

     

    1.采用單線程方式

    在該JSP文件中加上: ,使它以單線程方式執(zhí)行,這時,仍然只有一個實例,所有客戶端的請求以串行方 式執(zhí)行。這樣會降低系統(tǒng)的性能.

     2.對函數(shù)savebuy()加synchronized進(jìn)行線程同步,該JSP仍然以多線程方式執(zhí)行,但也會降低系統(tǒng)的性能

    public synchronized void savebuy() 

            
    }
     

     3.采用局部變量代替實例變量

    函數(shù)savebuy()聲明如下:因為在savebuy()中使用的是傳給他的形參,是在堆棧中分配的,所以是線程安全的

    public void savebuy(String name,String product, int quantity)
    {
          
    }

    調(diào)用方式改為:

    <% 
    String name 
    String product; 
    long quantity; 
    name
    =request.getParameter("name"); 
    product
    =request.getParameter("product"); 
    quantity
    =request.getParameter("quantity"); 
    savebuy(name,product,quantity) 
    %> 

    如果savebuy的參數(shù)很多,或這些數(shù)據(jù)要在很多地方用到,也可聲明一個類,并用他做參數(shù),如:

    public class buyinfo
    {
          String name;
          String product;
          
    long quantity;
    }
     
    public void savebuy(buyinfo info)
    {
          
    }

     調(diào)用方式改為:

    <% 
    buyinfo userbuy 
    = new buyinfo(); 

    userbuy.name
    =request.getParameter("name"); 
    userbuy.product
    =request.getParameter("product"); 
    userbuy.quantity
    =request.getParameter("quantity"); 
    savebuy(userbuy); 
    %>

     所以最好是用3,因為1,2會降低系統(tǒng)的性能. 多線程問題一般只有在在大并發(fā)量訪問時,才有可能出現(xiàn),并且很難重復(fù)出現(xiàn),所以應(yīng)在編程時就時刻注意。


    轉(zhuǎn)CSDN

    posted on 2007-05-24 11:14 cheng 閱讀(269) 評論(0)  編輯  收藏 所屬分類: JSP/Servlet
    主站蜘蛛池模板: 亚洲国产成人精品久久| 16女性下面无遮挡免费| 亚洲综合av一区二区三区不卡| 日韩一卡2卡3卡4卡新区亚洲| 四虎在线视频免费观看| 久久国产乱子免费精品| 黄色视屏在线免费播放| 午夜亚洲国产精品福利| 亚洲精品宾馆在线精品酒店| 亚洲国产精品人久久电影| 亚洲网址在线观看你懂的| 亚洲韩国精品无码一区二区三区| 亚洲精品一级无码鲁丝片| 国产无遮挡吃胸膜奶免费看 | 亚洲一区二区视频在线观看| 在线播放免费播放av片| 在线观看免费人成视频| aⅴ免费在线观看| 永久在线免费观看| 18禁止看的免费污网站| 久爱免费观看在线网站| 免费成人在线视频观看| 国产午夜免费高清久久影院| 最近中文字幕大全免费版在线| 中文字幕不卡免费视频| 两个人www免费高清视频| 国产精品成人69XXX免费视频| 老司机午夜免费视频| WWW亚洲色大成网络.COM| 久久久久久久久无码精品亚洲日韩| 亚洲中文无码亚洲人成影院| 亚洲一级特黄特黄的大片| 亚洲综合色区中文字幕| 亚洲av无码一区二区三区观看| 亚洲一本之道高清乱码| 亚洲日本va在线观看| 亚洲AV电影天堂男人的天堂| 激情小说亚洲图片| 一级人做人爰a全过程免费视频| 好吊色永久免费视频大全| 久久免费线看线看|