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

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

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

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    編寫線程安全的JSP程序

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


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


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


    實(shí)例變量

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

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

    JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是線程安全的,APPLICATION在整個系統(tǒng)內(nèi)被使用,所以不是線程安全的.

    局部變量

    局部變量在堆棧中分配,因?yàn)槊總€線程都有它自己的堆棧空間,所以是線程安全的.

    靜態(tài)類

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

    外部資源:

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

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



    <%@ page import="

    Java x.naming.*,

    java.util.*,

    java.sql.*,

    Web logic.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());

    }

    }

    }

    %>


    上面的程序模擬網(wǎng)上購物中的一部分,把用戶在瀏覽器中輸入的用戶名,購買的物品名稱,數(shù)量保存到表BUY中。在savebuy()函數(shù)中用到了實(shí)例變量,所以它不是線程安全的.因?yàn)?程序中的每一條語句都不是原子操作,如name= request.getParameter("name");在執(zhí)行是會對應(yīng)多個機(jī)器指令,在任何時候都可能因系統(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ù)量與保持到表中的數(shù)據(jù)不一致.這是個很嚴(yán)重的問題.

    三、解決方法


    采用單線程方式

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


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

    public synchronized void savebuy()

    {

    ......

    }


    采用局部變量代替實(shí)例變量,函數(shù)savebuy()聲明如下:

    因?yàn)樵趕avebuy()中使用的是傳給他的形參,是在堆棧中分配的,所以是線程安全的.

    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,因?yàn)?,2會降低系統(tǒng)的性能.

    多線程問題一般只有在在大并發(fā)量訪問時,才有可能出現(xiàn),并且很難重復(fù)出現(xiàn),所以應(yīng)在編程時就時刻注意。

    from: http://java.ccidnet.com/art/3737/20030321/530503_1.html

    posted on 2006-10-30 17:48 weidagang2046 閱讀(235) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲AV成人无码天堂| 又大又粗又爽a级毛片免费看| 亚洲狠狠爱综合影院婷婷| 亚洲精华液一二三产区| 成人免费午夜在线观看| jlzzjlzz亚洲jzjzjz| 99蜜桃在线观看免费视频网站| 亚洲妇熟XXXX妇色黄| 国产成人久久AV免费| 日产亚洲一区二区三区| 最新黄色免费网站| 亚洲国产成a人v在线| 久久久久久99av无码免费网站| 又黄又大的激情视频在线观看免费视频社区在线 | 99亚洲乱人伦aⅴ精品| 亚洲Av无码乱码在线播放| 日本精品久久久久久久久免费| 国产成人毛片亚洲精品| 国产免费一区二区视频| 久久久久亚洲精品无码系列| 亚欧免费视频一区二区三区 | 国产免费无码一区二区 | 中文字幕永久免费| 78成人精品电影在线播放日韩精品电影一区亚洲 | 日本免费电影一区二区| 美女扒开尿口给男人爽免费视频| 无码专区一va亚洲v专区在线| 99久久精品毛片免费播放| 337p日本欧洲亚洲大胆艺术| 亚洲精品美女久久久久99小说| 国产免费久久精品99re丫y| 黄色免费在线网址| 亚洲卡一卡二卡乱码新区| 亚洲精品国产高清嫩草影院| 成全高清视频免费观看| 日韩精品无码免费专区午夜 | 亚洲AV无码精品色午夜果冻不卡| 91精品免费久久久久久久久| 你懂的网址免费国产| 日韩免费码中文在线观看| 精品久久久久亚洲|