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

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

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

    隨筆 - 6  文章 - 0  trackbacks - 0
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(2)

    隨筆分類

    文章分類

    好友

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

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

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

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

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

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

    <%@ 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()
    {
        /*進行數據庫操作,把數據保存到表中*/
        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());
            }
        }
    }
    %>

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

    三、解決方法

    1. 采用單線程方式
      在該JSP文件中加上: <%@ page isThreadSafe="false" %>,使它以單線程方式執行,這時,仍然只有一個實例,所有客戶端的請求以串行方 式執行。這樣會降低系統的性能.
    2. 對函數savebuy()加synchronized進行線程同步,該JSP仍然以多線程方式執行,但也會降低系統的性能
      public synchronized void savebuy()
      {
             ......
      }
    3. 采用局部變量代替實例變量,函數savebuy()聲明如下:
      因為在savebuy()中使用的是傳給他的形參,是在堆棧中分配的,所以是線程安全的.
      public void savebuy(String name,String product, int quantity)
      {
            ......
      }

      調用方式改為:
      <%
      String name
      String product;
      long quantity;

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

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

      public class buyinfo
      {
            String name;
            String product;
            long quantity;
      }

      public void savebuy(buyinfo info)
      {
            ......
      }

      調用方式改為:
      <%
      buyinfo userbuy = new buyinfo();

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

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

    posted on 2006-03-02 14:22 badboy 閱讀(174) 評論(0)  編輯  收藏 所屬分類: Java基礎
    主站蜘蛛池模板: 国产精品免费久久久久电影网| MM1313亚洲精品无码久久| 99视频免费在线观看| 国产午夜亚洲不卡| 中文字幕在线视频免费观看| 亚洲AV成人精品日韩一区18p| 国产成人高清亚洲一区久久| 免费a级黄色毛片| 天堂亚洲免费视频| 久久精品国产亚洲AV不卡| 一区二区3区免费视频| 在线日韩日本国产亚洲| 视频免费在线观看| 亚洲av不卡一区二区三区| 外国成人网在线观看免费视频| 久久精品国产亚洲AV无码娇色| 午夜免费啪视频在线观看| 亚洲手机中文字幕| 在线观看免费精品国产| 牛牛在线精品观看免费正| 亚洲日韩乱码中文无码蜜桃臀网站| 久草视频在线免费看| 亚洲在成人网在线看| 国产美女无遮挡免费视频网站| 在线播放国产不卡免费视频| 国产亚洲精品一品区99热| 91热成人精品国产免费| 精品亚洲av无码一区二区柚蜜| 亚洲午夜无码片在线观看影院猛| 日韩插啊免费视频在线观看 | 三级黄色片免费看| 亚洲高清在线视频| 永久免费AV无码国产网站| 男女污污污超污视频免费在线看| 久久久久久久久亚洲| 免费网站看v片在线香蕉| 三级黄色片免费看| 亚洲熟妇丰满xxxxx| 亚洲午夜福利AV一区二区无码| 97无码免费人妻超级碰碰夜夜| 巨胸喷奶水www永久免费|