亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? connectionpool.java

?? 中國電信小靈通短信平臺SP端程序
?? JAVA
字號:
package com.pansonlu.common.database;

import java.sql.*;
import java.util.*;

/**
 * <p>
 * 數據庫連接池。
 * 池里每個連接的最大活躍期是24小時,過期則自動重新連接數據庫(以保證性能穩定)。
 * 如果連接池中的某個連接因為某個原因被數據庫斷開連接,則系統把該連接從連接池移出。
 * 客戶端請求連接時,如果當前沒有空閑連接,而連接總數小于連接池最大容量,則新建
 * 連接加入到連接池
 * </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2008</p>
 * <p>Company: </p>
 * @author hmy
 * @version 2004-06-11
 */

import com.pansonlu.common.util.*;

public class ConnectionPool {
  public static final long SECOND = 1000;  //秒
  public static final long MINUTE = SECOND*60;   //分
  public static final long HOUR = MINUTE*60;   //小時

  //一個數據庫連接的有效期。超過有效其的連接應該被釋放,連接池重新建立一個連
  // 接來代替它,默認為24(單位:小時)
  //一個連接建立后,使用一定時間后,應該釋放,重新建立一個連接代替它,否則
  //一個連接時間長了會出現性能和可靠性不穩定
  private final static int CONNECTION_ALIVE_TIME = 24;

  private int poolSize;    //連接池大小
  private long timeout;   //連接時的time out設置(單位:分鐘)。必須大于0,默認為30

  private String driver = null; //驅動程序類
  private String dbURL = null;  //數據庫服務器URL地址
  private String username = null;   //訪問數據庫的用戶名
  private String password = null;   //訪問數據庫的密碼

  /**
   * 用來測試的數據庫連接的有效性的數據表的表名。要求數據
   * 庫里存在這個表,而且這個表屬于這個用戶;至于這個表有
   * 些什么字段,有多少記錄,都不重要(記錄條數最好不要超過10條,可以沒有記錄)。
   * 這個屬性的值可以為null,如果為null,則對某些數據庫,這個連接池可能失去自動重連
   * 的功能(即在數據庫服務器重新啟動或網絡連接短暫斷開后,
   * 該連接池無法自動重新連接數據庫)。
   */
  private String testTableName = null;

  /**
   * 物理連接池(包含所有物理數據庫連接,不論是否被用戶占用)。
   * 本集合的大小即代表與數據庫的總連接數。
   * 集合中每個元素都是一個java.sql.Connection對象。
   */
  private Vector  allConns;

//  /**
//   * 所有連接(包裝)的池子
//   */
//  private Vector allWrappers;

  /**
   * 空閑連接(包裝)池(只包含未被用戶占用的連接)。
   * 本集合的大小即代表當前空閑數據庫連接(未被用戶占用)的數目。
   * 里面的每個元素都是一個ConnectionWrapper對象。用戶請求連接時,
   * 系統從本集合中取得ConnectionWrapper對象,同時把該對象從本集合中移除。
   */
  private Vector freeWrappers;

  private static ConnectionPool pool = null;

  /**
   *
   * @param driver  驅動程序類名
   * @param dbURL      數據庫服務器的URL地址
   * @param username    數據庫用戶名
   * @param password    數據庫用戶的密碼
   * @param test_table_name   參見屬性testTableName的說明
   * @param poolSize    連接池大小
   * @param timeout     timeout設置,單位:分
   */
  private ConnectionPool(
      String driver,
      String dbURL,
      String username,
      String password,
      int poolSize,
      int timeout) throws Exception{
    this.driver = driver.trim();
    this.dbURL = dbURL.trim();
    this.username = username.trim();
    this.password = password.trim();
    this.timeout = timeout;
    this.poolSize = poolSize;

//    if(testTableName!=null && testTableName.trim().length()==0){
//      testTableName = null;
//    }

    allConns = new Vector(poolSize);
    freeWrappers = new Vector(poolSize);

    try{
      Class.forName(driver);

      for(int i=0;i<poolSize;i++){//根據池的大小,建立若干個連接,放入池中
        addConnection();
      }
    }catch(Exception e){
      for(int i=0;i<allConns.size();i++){
        try{
          //關閉所有已經取得的物理連接
          ((Connection)allConns.get(i)).close();
        }catch(Exception eee){}
      }//end for i
      allConns.clear();
      freeWrappers.clear();
      throw e;
    }//end try

    //啟動檢查線程,定期對過期連接進行釋放、重新連接的工作
    (new ReCreateThread()).start();
    (new ReConnectThread()).start();

  }//end of method

  private void addConnection() {
    try{
      Connection conn = DriverManager.getConnection(dbURL, username, password); //建立連接
      ConnectionWrapper wrapper = new ConnectionWrapper(conn, freeWrappers);

      allConns.addElement(conn); //把物理連接放入數據庫連接池中
      //把物理連接放入包裝器后,放入空閑連接池中
      freeWrappers.addElement(wrapper);
    }catch (SQLException e) {
      System.out.println("ConnectionPool,addConnection(),新建數據庫鏈接失敗,原因:"+e);
    }
  }

  /**
   * 初始化數據庫連接池
   * @param driver
   * @param url
   * @param user
   * @param password
   * @param  testTableName  用來測試的數據庫連接的有效性的數據表的表名。要求數據
   *                      庫里存在這個表,而且這個表屬于這個用戶;至于這個表有
   *                      些什么字段,有多少記錄,都不重要(記錄條數最好不要超過10條,
   *                      可以沒有記錄)。這個參數可以為null,
   *                      如果為null,則對某些數據庫,這個連接池可能失去自動重連
   *                      的功能(即在數據庫服務器重新啟動或網絡連接短暫斷開后,
   *                      該連接池無法自動重新連接數據庫)。
   * 連接池將用這個表
   * @param size   連接池大小
   * @param timeout     連接超時設置(單位:秒)
   */
  public static void initConnectionPool(String driver,String url,String user,
          String password, int size,int timeout) throws SQLException {
    if(pool!=null){ //連接池已經建立
      return;
    }

    try{
      pool = new ConnectionPool(driver,url,user,password,size,timeout);
    }catch(Exception e){
      throw new SQLException(e.toString());
    }
  }

  /**
   * 從空閑連接池取得連接。
   * @return 取得的連接
   * @throws   遇到SQL異常則拋出,連接超時也拋出異常。
   */
  public static Connection getConnection() throws SQLException {
    if(pool==null){
      throw new SQLException("異常,ConnectionPool,getConnection(),連接池尚未初始化");
    }

    ConnectionWrapper wrapper;
    Connection conn = null;
    long startTime = System.currentTimeMillis(); //發起請求的時間
    while(conn==null && System.currentTimeMillis()-startTime<SECOND*pool.timeout){
      synchronized(pool.freeWrappers){
        if (pool.freeWrappers.size() > 0) {
          //從空閑連接池取出連接。
          //從連接池取出連接時從隊列的最前面取,把連接放回連接池時放到隊列的最后
          wrapper = (ConnectionWrapper) pool.freeWrappers.remove(0);
          return wrapper;
        }else{  //如果沒有空閑連接
          if(pool.allConns.size()<pool.poolSize){  //有效物理連接不夠
            pool.addConnection();   //增加連接
          }
        }
      }//end  synchronized

      try{
        Thread.sleep(SECOND);   //等待1秒
      }catch(Exception e){
        //
      }
    }//end while

    throw new SQLException("ConnectionPool,getConnection,請求連接超時");

  }//end of method

  /**
   * 定期檢查物理連接池里的連接,如果某個連接被數據庫斷開了,則重新建立連接替
   * 代它,同時要對空閑連接(包裝)池做處理
   */
  private class ReConnectThread extends Thread{
    public void run(){
      while(true){
        try {
          Thread.sleep(10 * SECOND); //間隔10秒
        }
        catch (Exception e) {
          //
        }

        deleteInvalidConns();  //刪除物理連接池里的無效連接
        deleteInvalidWrappers();   //刪除無效的連接包裝器
      }//end while
    }

    private void deleteInvalidWrappers(){
      if(allConns.size()==poolSize){
        return;
      }

      synchronized(freeWrappers){
          ConnectionWrapper wrapper = null;
          Connection conn = null;
          for(int i=freeWrappers.size()-1;i>=0;i--){
            wrapper = (ConnectionWrapper)freeWrappers.get(i);
            conn = wrapper.getPhysicalConnection();
            if(allConns.contains(conn)==false){  //說明該包裝器已經無效
              freeWrappers.remove(wrapper);   //刪除無效包裝器
            }//end if
          }//end for i
      }//end synchronized

    }//end method

    private void deleteInvalidConns(){
      synchronized(allConns){
        Connection conn = null;
        for(int i=allConns.size()-1;i>=0;i--){
          conn = (Connection)allConns.get(i);
          if(testConnection(conn)==false){
            try{
              conn.close();  //關閉物理連接
            }catch(Exception e){}
            allConns.remove(conn);  //刪除無效物理連接
          }
        }//end for i
      }//end synchronized
//      System.out.println("連接池大小:"+allConns.size());
    }

    /**
     * 檢查一個數據庫連接是否有效
     * @param conn
     * @return   有效則返回true
     */
    private boolean testConnection(Connection conn){
      Statement stmt = null;
      ResultSet rs = null;
      boolean flag = false;
      try{
        stmt = conn.createStatement();  //測試是否有效
        //if(testTableName!=null){
          //String sql = "select getdate()";            //測試SQL,根據不同的數據庫更改
          //rs = stmt.executeQuery(sql);
        //}

        flag = true;   //沒出異常,說明連接有效
//       System.out.println("------testConnection(),連接有效");
      }catch(SQLException e){
//        System.out.println("------testConnection(), table name: "+testTableName);
//        System.out.println("------testConnection(), 異常:");
//        e.printStackTrace();
        flag = false;  //認定連接無效
      }finally{
        if(rs!=null)
          try{
            rs.close();
          }catch(Exception ee){}

        if(stmt!=null)
          try{
            stmt.close();
          }catch(Exception ee){}
      }
      return flag;
    }//end of method testConnection

  }

  /**
   * 負責釋放過期的數據庫連接、重新建立連接替代它的線程
   * <p>Title: </p>
   * <p>Description: </p>
   * <p>Copyright: Copyright (c) 2008</p>
   * <p>Company: </p>
   * @author hmy
   * @version 1.0
   */
  private class ReCreateThread extends Thread{
    public void run(){
      while(true){
        try{
          Thread.sleep(HOUR);   //等待一個小時
        }catch(Exception e){}

        recreateConns();  //檢查連接池中的連接,對于已經過期的,釋放,用新的連接代替
      }//end for while
    }

    //在空閑連接池中檢查已經過期的連接,將它釋放,新建一個連接代替它
    private void recreateConns(){
      //Debug.outInfo("ConnectionPool,ReCreateThread,巡視,檢查過期連接");
      //用來存儲需要被釋放、重新連接的ConnectionWrapper對象
      //已經超過有效期的、當前正處于空閑狀態的ConnectionWrapper對象需要被釋放、重連
      Vector timeouts = new Vector();

      //從空閑連接池取出所有過期連接,放入timeouts集合中
      long currTime = System.currentTimeMillis(); //當前時間
      ConnectionWrapper wrapper = null;

      synchronized(freeWrappers){
        //當前長度。本次操作期間,被用戶返回連接池的連接放到了隊列的最后,本次不操作它
        int currSize = freeWrappers.size();

        //遍歷空閑連接池中的連接(因為有刪除操作,所以從后面開始),把該釋放的對象取出
        for (int i = currSize-1; i>=0; i--) {
          wrapper = (ConnectionWrapper) freeWrappers.get(i);

          //如果連接已經過了有效期:
          if (currTime - wrapper.getCreatedTime() > HOUR * CONNECTION_ALIVE_TIME) {//已經超時
            timeouts.addElement(freeWrappers.remove(i));
          }//end if
        }//end for i
      }//end synchronized


      //把需要重新連接的對象釋放,并新建連接替代它
      Connection timeoutConn;   //過期的物理連接
      Connection newConn;   //新的物理連接
      for(int i=0;i<timeouts.size();i++){
        wrapper = (ConnectionWrapper)timeouts.get(i);
        timeoutConn = wrapper.getPhysicalConnection();  //取得包裝器所包裝的物理連接
        try{
          allConns.remove(timeoutConn);   //把過期物理連接從物理連接池移除
          timeoutConn.close();   //釋放過期物理連接

          newConn = DriverManager.getConnection(dbURL,username,password);//新建一個物理連接
          allConns.addElement(newConn);  //放入物理連接池
          //包裝后放入空閑連接池:
          freeWrappers.addElement(new ConnectionWrapper(newConn,freeWrappers));
        }catch(Exception e){
          //
        }
      }//end for i

    }//end of method

  }//end class ReCreateThread


  //測試
  public static void main(String[] args){
    Connection conn = null;

    int m = 1;

    while(true){
      try{
        //取得連接,持有1秒再釋放
        conn = ConnectionPool.getConnection();
        Debug.outInfo("得到連接:   "+conn);
        Debug.outInfo("conn.getAutoCommit(): "+conn.getAutoCommit());

        Thread.sleep(1000);  //等待1秒

        conn.close();
        Debug.outInfo("conn.getAutoCommit(): "+conn.getAutoCommit());

        Debug.outInfo("------------------------------");
      }catch(Exception e){
        e.printStackTrace();
        //Debug.outInfo("main(), e: "+e);
      }

    }//end  while


  }//end of method


}//end file


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产乱子伦一区二区三区国色天香| 国产日韩影视精品| 午夜精品久久久久久久99樱桃| 欧美怡红院视频| 亚洲成av人综合在线观看| 3751色影院一区二区三区| 日韩av电影天堂| 26uuu久久天堂性欧美| 国产福利精品一区二区| 国产精品久久三| 在线精品亚洲一区二区不卡| 婷婷综合另类小说色区| www亚洲一区| 色综合天天在线| 喷白浆一区二区| 国产欧美精品国产国产专区| 色一情一伦一子一伦一区| 日韩国产欧美在线播放| 日本一区二区三区视频视频| 色偷偷久久一区二区三区| 日韩成人免费在线| 欧美激情一二三区| 欧美男同性恋视频网站| 国产精品夜夜嗨| 一区二区在线观看免费| 欧美哺乳videos| 91女神在线视频| 精彩视频一区二区| 亚洲男人的天堂一区二区| 欧美一级精品在线| 99久久综合99久久综合网站| 视频一区二区三区入口| 国产精品日产欧美久久久久| 欧美美女直播网站| 成人avav影音| 男人的j进女人的j一区| 亚洲视频免费观看| 欧美日韩亚洲丝袜制服| 国产福利一区二区| 日韩一区欧美二区| 亚洲啪啪综合av一区二区三区| 日韩欧美电影在线| 色婷婷av一区二区三区gif | 国产精品国产三级国产aⅴ入口| 欧美日韩一区二区欧美激情| 国产精品77777竹菊影视小说| 天天爽夜夜爽夜夜爽精品视频| 国产精品免费免费| 精品粉嫩超白一线天av| 欧美三级日韩三级国产三级| 不卡的电影网站| 国产在线一区二区| 免费人成在线不卡| 亚洲国产sm捆绑调教视频 | 成人动漫一区二区| 久久99国产精品久久99| 亚洲成人综合视频| 亚洲精品第1页| 国产精品成人在线观看| 久久视频一区二区| 日韩欧美久久久| 欧美一区二区在线免费播放| 色婷婷av一区| 色综合一个色综合亚洲| 97se亚洲国产综合在线| 高清在线观看日韩| 国产福利一区二区三区在线视频| 精品在线播放午夜| 免费在线看成人av| 日韩国产欧美在线观看| 午夜久久久久久久久久一区二区| 夜夜嗨av一区二区三区网页| 亚洲精品乱码久久久久久日本蜜臀| 国产精品美女www爽爽爽| 久久久久国产一区二区三区四区 | 91传媒视频在线播放| k8久久久一区二区三区| 成人精品免费视频| 成人av免费网站| 99久久精品免费看| 91丝袜高跟美女视频| 91蝌蚪国产九色| 欧美亚洲丝袜传媒另类| 欧美色区777第一页| 欧美精品v国产精品v日韩精品| 69堂亚洲精品首页| 日韩精品一区在线| 久久日韩粉嫩一区二区三区| 久久精品视频免费| 国产精品美女久久久久久久久| 亚洲欧洲色图综合| 亚洲国产日韩精品| 青青草国产成人99久久| 久久草av在线| 丁香婷婷综合网| 91在线观看高清| 欧美日韩三级一区| 日韩欧美国产一区在线观看| 久久日韩精品一区二区五区| 国产三级欧美三级日产三级99 | 一道本成人在线| 欧美日韩在线一区二区| 欧美一区二区黄| 久久久久久久久蜜桃| 中文字幕中文字幕中文字幕亚洲无线| 亚洲精品国产视频| 热久久国产精品| 成人免费三级在线| 色先锋资源久久综合| 日韩视频免费观看高清完整版在线观看 | 91福利区一区二区三区| 7777精品伊人久久久大香线蕉经典版下载 | 欧美成人伊人久久综合网| 久久久久久麻豆| 亚洲精品国产精华液| 久88久久88久久久| 色综合久久中文综合久久牛| 欧美精品高清视频| 国产女人18毛片水真多成人如厕 | 国产精品高潮呻吟| 日本不卡视频一二三区| 成人av电影观看| 欧美一区二区福利在线| 亚洲男人的天堂av| 激情欧美日韩一区二区| 一本大道久久精品懂色aⅴ| 日韩精品中文字幕一区| 一区二区三区在线视频免费| 国内精品在线播放| 欧美视频第二页| 国产精品毛片高清在线完整版| 日本va欧美va精品发布| 色哟哟欧美精品| 国产亚洲一区二区三区四区 | 久久国产精品第一页| 色婷婷久久久综合中文字幕| 国产亚洲欧美色| 秋霞电影网一区二区| 欧美午夜片在线观看| 中国av一区二区三区| 国产综合色在线| 3atv在线一区二区三区| 一区二区三区自拍| proumb性欧美在线观看| 久久精品视频在线免费观看| 久久国产精品99精品国产 | 日韩精品一区二区三区中文精品| 亚洲精品菠萝久久久久久久| 成人免费视频国产在线观看| 久久亚区不卡日本| 久久国内精品视频| 欧美一区二区三区日韩视频| 亚洲3atv精品一区二区三区| 色94色欧美sute亚洲13| 中文字幕一区二区在线观看| 国产不卡高清在线观看视频| 久久综合99re88久久爱| 美女一区二区视频| 在线观看91av| 石原莉奈一区二区三区在线观看| 91亚洲国产成人精品一区二三| 中文字幕欧美三区| 成人性生交大片| 国产日韩精品视频一区| 国产91精品一区二区麻豆网站| 久久久久久久av麻豆果冻| 国产一区二区毛片| 国产亚洲欧洲997久久综合| 国产精品综合一区二区| 久久精品亚洲精品国产欧美 | 国产精品―色哟哟| 岛国精品在线观看| 国产精品久久久久久福利一牛影视| 国产又粗又猛又爽又黄91精品| 2023国产精品自拍| 国产mv日韩mv欧美| 国产精品久久午夜| 91成人看片片| 亚洲成人福利片| 日韩欧美亚洲国产另类 | 午夜精品福利一区二区三区蜜桃| 欧美日韩一二三| 美国十次综合导航| 国产欧美日韩另类一区| 94-欧美-setu| 亚洲成人激情自拍| 精品毛片乱码1区2区3区| 高清国产一区二区三区| 亚洲欧美aⅴ...| 4438x成人网最大色成网站| 久久99国产精品成人| 中文字幕欧美国产| 日本韩国视频一区二区| 青青草国产精品97视觉盛宴| 国产午夜亚洲精品不卡| 91国内精品野花午夜精品| 蜜桃精品视频在线| 国产精品久久久久久妇女6080| 欧美色综合影院| 国产一区二区在线免费观看|