天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

編寫線程安全的JSP程序

作者:徐春金

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

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

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

  1. 實(shí)例變量
    實(shí)例變量是在堆中分配的,并被屬于該實(shí)例的所有線程共享,所以不是線程安全的.
  2. JSP系統(tǒng)提供的8個(gè)類變量
    JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是線程安全的,APPLICATION在整個(gè)系統(tǒng)內(nèi)被使用,所以不是線程安全的.
  3. 局部變量
    局部變量在堆棧中分配,因?yàn)槊總€(gè)線程都有它自己的堆棧空間,所以是線程安全的.
  4. 靜態(tài)類
    靜態(tài)類不用被實(shí)例化,就可直接使用,也不是線程安全的.
  5. 外部資源:
    在程序中可能會(huì)有多個(gè)線程或進(jìn)程同時(shí)操作同一個(gè)資源(如:多個(gè)線程或進(jìn)程同時(shí)對(duì)一個(gè)文件進(jìn)行寫操作).此時(shí)也要注意同步問題.

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

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

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

三、解決方法

  1. 采用單線程方式
    在該JSP文件中加上: <%@ page isThreadSafe="false" %>,使它以單線程方式執(zhí)行,這時(shí),仍然只有一個(gè)實(shí)例,所有客戶端的請(qǐng)求以串行方 式執(zhí)行。這樣會(huì)降低系統(tǒng)的性能.
  2. 對(duì)函數(shù)savebuy()加synchronized進(jìn)行線程同步,該JSP仍然以多線程方式執(zhí)行,但也會(huì)降低系統(tǒng)的性能
    public synchronized void savebuy()
    {
           ......
    }
  3. 采用局部變量代替實(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ù)要在很多地方用到,也可聲明一個(gè)類,并用他做參數(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會(huì)降低系統(tǒng)的性能.
多線程問題一般只有在在大并發(fā)量訪問時(shí),才有可能出現(xiàn),并且很難重復(fù)出現(xiàn),所以應(yīng)在編程時(shí)就時(shí)刻注意。

jsp技術(shù)編寫線程安全的JSP程序,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 日日干夜夜爱 | 国产成人一区免费观看 | WWW国产精品内射老师 | 亚洲国产欧美在线看片 | 日韩中文字幕亚洲无线码 | 国产亚洲精品久久久999密臂 | 丝瓜视频樱桃视频在线观看免费 | 91精品免费久久久久久久久 | 宝贝乖女好紧好深好爽老师 | 99久久国产综合精品成人影院 | 亚洲欧美一区二区久久 | 99久久精品久久久 | 动漫美女禁区图 | 久久成人免费观看全部免费 | 小sao货ji巴cao死你视频 | 天美传媒在线观看免费完整版 | 亚洲AV无码乱码国产麻豆穿越 | 国产亚洲精品久久久久久禁果TV | 欧美另类与牲交ZOZOZO | 伊人久99久女女视频精品免 | 国产亚洲精品线视频在线 | 中文人妻熟妇精品乱又伧 | 亚洲VA欧美VA天堂V国产综合 | 亚洲 欧美 中文 日韩 视频 | 久久re视频这里精品一本到99 | 日本理论片和搜子同居的日子2 | 午夜伦伦电影理论片大片 | 久久精品AV一区二区无码 | 国产成人免费在线观看 | 乌克兰粉嫩摘花第一次 | 攻把受做哭边走边肉楼梯PLAY | 中文字幕视频免费在线观看 | 日韩高清在线亚洲专区 | 99久久蜜臀AV免费看蛮 | 一一本之道高清手机在线观看 | 尤物国产在线精品三区 | 亚洲 综合 欧美在线视频 | 快播看黄片| 美女洗澡脱得一二干净 | 最新无码专区在线视频 | 久艾草在线精品视频在线观看 |