java 数据库连接池

数据库连接池,是一种相当实用的应用程序。它可以保存、维护及创建用户所需的数据库连接。从而使得用户得到一个连接的时间降低90%以上。大大提升了数据库访问的反应时间。

 

这个是一个开源的代码。大家可以修改它、使用它。

 

希望我的代码能对大家有用。

 

此代码,经过1000数量级的多线程并发访问测试。在四核CPU下也进行了多线程测试。保证了连接池在真多线程上同步访问的安全性。

里面包含了一个公开的接口。使用这个接口里面的函数。可以轻易创建使用数据库连接池服务。

使用一个守护线程维护这个连接池,完全自动化。

 

下载连接:http://download.csdn.net/user/lauo1188

 

 

连接池接口类:

 

  1. package mysql;  
  2. import java.sql.*;  
  3. import java.sql.ResultSet;  
  4. public interface Pool  
  5. {  
  6.     public boolean start(String dbname,String user,String psw);  //启动数据库连接池服务  
  7.     //以下start函数将允许用户设置最低空闲连接数,最高空闲连接数,最大连接数  
  8.     public boolean start(int lows,int maxs,int maxc,String dbname,String user,String psw);  
  9.     public Connection getConnection();  //得到连接器  
  10.     public boolean freeConnection(Connection con);//将连接返回到连接池中  
  11.     public boolean close(); //清除连接池,并且关闭它(使之变得不可用)  
  12. }  

 

 

 

第一个实现类:VectorPool

 

 

  1. /** 
  2.  * @(#)Pool.java 
  3.  * 
  4.  * 
  5.  * @author  lauo 
  6.  * @version 1.00 2010/5/15 
  7.  * 
  8.  * 测试完成于2010-5-16  22:40分 
  9.  */  
  10. package mysql;  
  11. import mysql.*;  
  12. import java.sql.*;  
  13. import java.util.*;  
  14. /* 
  15.  *这里将实现ConnectionPool接口 
  16.  */  
  17. public class VectorPool extends Thread implements Pool   
  18. {  
  19.     protected final boolean debug = false//是否debug态(如是  输出debug状态信息)  
  20.     protected boolean init = false;//是否已经将setting初始化  
  21.     //timeDiff   一个连接超过此时间未使用过,则需要更新此连接----1小时  
  22.     protected final long timeDiff =  60*60*1000 ;//1小时60分钟,1分钟60秒,1秒1000毫秒  
  23.     protected int lows = 20 ; //连接池的最小空闲连接数  
  24.     protected int maxs = 100 ; //连接池的最大空闲连接数  
  25.     protected int maxc = 100;  
  26.     protected String dbname = null;  
  27.     protected String user = null;  
  28.     protected String psw = null;  
  29.       
  30.     protected Integer conCount = 0//这个是静态的。当前连接数  
  31.     //下面是连接保存的池  
  32.     protected Vector<ConInfo> pool = new Vector<ConInfo>();  
  33.     public VectorPool()   
  34.     {  
  35.     }  
  36.     public void start()  
  37.     {  
  38.           
  39.     }  
  40.     //得到当前连接数  
  41.     protected int getConCount()  
  42.     {  
  43.         return conCount;  
  44.     }  
  45.     /* 
  46.      *设置数据库连接的基本参数 
  47.      */  
  48.     public  synchronized  boolean start(String db,String u,String p)  
  49.     {  
  50.         if(false == init && null != pool)//如果未初始化,且连接池可用  
  51.         {  
  52.             dbname  =   db;  
  53.             user    =   u;  
  54.             psw     =   p;  
  55.             if(test())  
  56.             {  
  57.                 init    =   true;  
  58.                 super.start();   
  59.                 return true;  
  60.             }  
  61.             else return false;  
  62.         }  
  63.         else  
  64.             return false;  
  65.     }  
  66.     public synchronized boolean start(int l,int m,int mc,String db,String u,String p)  
  67.     {  
  68.         if(l<0 || m<0 ||l>=m || m>mc)//0<l<m<=mc  
  69.             return false;  
  70.         if(false == init && null != pool)//如果未初始化,且连接池可用  
  71.         {  
  72.             dbname  =   db;  
  73.             user    =   u;  
  74.             psw     =   p;  
  75.             if(test())  
  76.             {  
  77.                 init    =   true;  
  78.                 lows = l<5?5:l;  //这里允许的最小的值为5  
  79.                 maxs = m<10?10:m; //这里允许的最小的值为10  
  80.                 maxc = mc<20 ?20:mc;//这里允许的连接数  
  81.                 super.start();   
  82.                 return true;  
  83.             }  
  84.             else   
  85.                 return false;  
  86.         }  
  87.         else  
  88.             return false;  
  89.     }  
  90.     /* 
  91.      *从连接池得到一个连接 
  92.      */  
  93.     public synchronized Connection getConnection()  
  94.     {  
  95.           
  96.         if(init)  
  97.         {  
  98.             ConInfo c = getOneConnection();  
  99.             return c!=null?c.con:null;//安全得到一个连接  
  100.         }  
  101.         else  
  102.             return null;  
  103.     }  
  104.     /* 
  105.      *得到一个连接,包含了lastTime信息 
  106.      */  
  107.     protected synchronized ConInfo getOneConnection()  
  108.     {  
  109.         if(pool.size()!=0)  
  110.         {  
  111.             return pool.remove(0);  
  112.         }  
  113.         else //如果连接池为空,创建新的连接  
  114.         {  
  115.             if(debug) System.out.println("new connection!");  
  116.             return newConInfo();  
  117.         }  
  118.     }  
  119.     /* 
  120.      *将一个连接放回到连接池中 
  121.      */  
  122.     public synchronized boolean freeConnection(Connection con)  
  123.     {  
  124.         if(init==false || con == null )//当没有init或者已经close之后 不应该free它进来。  
  125.             return false;  
  126.         ConInfo c =  new ConInfo(con);//调用了ConInfo的构造函数  
  127.         pool.addElement(c);  
  128.         return true;  
  129.     }  
  130.     /* 
  131.      *将内容清空 
  132.      *且将本连接池对象置为无用状态 
  133.      */  
  134.     public synchronized  boolean close()  
  135.     {  
  136.         if(init)  
  137.         {  
  138.             init = false;  
  139.             for(int i = 0; i <pool.size();i++)  
  140.                 pool.get(i).close();  
  141.             pool.clear();  
  142.             pool    =   null;//将此连接池置为无用状态。如果要新的链接池,重新创建链接池对象  
  143.             dbname  =   null;  
  144.             user    =   null;  
  145.             psw     =   null;  
  146.             return true;  
  147.         }  
  148.         else   
  149.             return false;  
  150.     }  
  151.      
  152. ////////////////////////////////////////////////////////////////  
  153.     /* 
  154.      *下面将是一个一线程执行体,当start连接池服务之后,由它来维护 
  155.      *连接池里面的连接,从而保证他们能被正确的创建、注销 
  156.      * 
  157.      */  
  158.     public void run()  
  159.     {  
  160.         final long sleepTime = 2*1000  ; //2秒   
  161.         final long refreshTime = 10*60*1000//10分钟运行一次。连接是否应该被更新  
  162.         final long lowsCheckTime = 2*1000;//10秒检查一次。最低连接数检查间隔时间  
  163.         final long maxsCheckTime = 60*1000;//1分钟检查一次。最大连接数时间  
  164.         long loop = 0;  
  165.         while(true)  
  166.         {  
  167.             if(loop%refreshTime == 0)  
  168.             {  
  169.                 if(debug) System.out.println("call refresh:"+pool.size());  
  170.                 refreshByTimeDiff();  
  171.             }  
  172.             if(loop%maxsCheckTime == 0)  
  173.             {  
  174.                 if(debug) System.out.println("call toMaxs:"+pool.size());  
  175.                 toMaxs();  
  176.             }  
  177.             if(loop%lowsCheckTime == 0)  
  178.             {  
  179.                 if(debug) System.out.println("conCnt:"+conCount+" call toLows:"+pool.size());  
  180.                 toLows();  
  181.             }  
  182.             loop += sleepTime;//更新loop的时间。  
  183.             try{  
  184.                 sleep(sleepTime);  
  185.             }  
  186.             catch(Exception e){  
  187.                 e.printStackTrace();  
  188.                 stop();  
  189.             }  
  190.               
  191.         }  
  192.           
  193.     }  
  194.     /* 
  195.      *使过小的空闲连接数恢复到lows 
  196.      */  
  197.     protected void toLows()  
  198.     {  
  199.         int size = pool.size();  
  200.         /* 
  201.          *这里要避免直接使用pool.size进行判断 
  202.          *当连接一直被get出去之后,size很难达到lows,故此 
  203.          */  
  204.         for(;size<lows;size++)  
  205.         {  
  206.             if(debug) System.out.println("toLows is running!");  
  207.             ConInfo c =  newConInfo();  
  208.             if(c!=null)  
  209.                 synchronized(pool)  
  210.                 {  
  211.                     pool.addElement(c);  
  212.                 }  
  213.         }  
  214.     }  
  215.     /* 
  216.      *使过多的空闲连接数恢复到maxs; 
  217.      */  
  218.     protected void toMaxs()  
  219.     {  
  220.         int size = pool.size();  
  221.         for(;size>maxs;size--)  
  222.         {  
  223.             if(debug) System.out.println("toMaxs is running!");  
  224.             try{  
  225.                 getConnection().close();  
  226.                 synchronized(conCount)//这里修改要同步好。  
  227.                 {  
  228.                     conCount --;  
  229.                 }  
  230.             }  
  231.             catch(Exception e)  
  232.             {  
  233.                 e.printStackTrace();  
  234.             }  
  235.         }  
  236.     }  
  237.     /* 
  238.      *查找当前的连接池,找到timeDiff时间内未使用过的连接,删除它们,如果连接数不足,将由toLows补齐 
  239.      *一个危险的线程不安全函数 
  240.      */  
  241.     public void refreshByTimeDiff()  
  242.     {  
  243.         Calendar nowTime = Calendar.getInstance();  
  244.         long now = nowTime.getTimeInMillis();  
  245.         for(int i=0;i<pool.size();i++)  
  246.         {  
  247.             ConInfo c = getOneConnection();  
  248.             if(now  - c.lastTime.getTimeInMillis() >=timeDiff)//删除它们  
  249.             {  
  250.                 if(debug) System.out.println("refresh the pool!,,,,,,,,");  
  251.                 synchronized(pool)//获得pool的锁  
  252.                 {  
  253.                     pool.remove(i).close();//使用了ConInfo中的关闭函数  
  254.                 }  
  255.             }  
  256.         }  
  257.     }  
  258.     /* 
  259.      *一个测试数据库连接是否可用的函数 
  260.      */  
  261.     protected boolean test()  
  262.     {  
  263.         int cnt = 10;  
  264.         Connection c;  
  265.         do{  
  266.             c = newConnection();  
  267.             cnt -- ;  
  268.         }while(c==null && cnt>=0);  
  269.         if(c!=null)  
  270.         {  
  271.             (new ConInfo(c)).close();  
  272.             return true;  
  273.         }  
  274.         else  
  275.             return false;  
  276.               
  277.     }  
  278. ////////////////////////////////////////////////////////////////  
  279.     /* 
  280.      *下面为内置的类,用于表明一个连接最后使用时间 
  281.      */  
  282.     class ConInfo  
  283.     {  
  284.         protected Calendar lastTime;    //连接最后使用时间  
  285.         protected Connection con = null;    //对应的connection  
  286.         public ConInfo(Connection c)  
  287.         {  
  288.             con =   c;  
  289.             lastTime = Calendar.getInstance();  
  290.         }  
  291.         public synchronized void close()  
  292.         {  
  293.             try  
  294.             {  
  295.                 if(con!=null)  
  296.                     con.close();  
  297.                 synchronized(conCount)  
  298.                 {  
  299.                     conCount-=con!=null?1:0;  
  300.                 }  
  301.                 lastTime = null;  
  302.             }  
  303.             catch(Exception e)  
  304.             {  
  305.                 e.printStackTrace();  
  306.             }  
  307.         }  
  308.     }  
  309.     /* 
  310.      *创建一个新的连接 
  311.      */  
  312.     protected  Connection newConnection()  
  313.     {  
  314.         try  
  315.         {  
  316.             Class.forName("com.mysql.jdbc.Driver");  
  317.             int cnt = 0;  
  318.             Connection c = null;  
  319.             synchronized(conCount)  
  320.             {  
  321.                 if(conCount<=maxc)//当连接数没超过既定最大连接数时  
  322.                 do  
  323.                 {  
  324.                     try{  
  325.                     c = DriverManager.getConnection(dbname,user,psw);  
  326.                     }catch(Exception es){c=null;if(debug) System.out.println("create new connection error!");}  
  327.                     cnt++;  
  328.                 }while(null == c  && cnt<3);  
  329.                 conCount+=c!=null?1:0;  
  330.             }  
  331.             return c;//创建一个新的connection  
  332.         }  
  333.         catch(Exception e)  
  334.         {  
  335.             e.printStackTrace();  
  336.             return null;  
  337.         }  
  338.     }  
  339.     /* 
  340.      *得到一个新的连接 
  341.      */  
  342.     protected ConInfo newConInfo()  
  343.     {  
  344.         Connection c = newConnection();  
  345.         if(c==null)  
  346.             return null;  
  347.         return new ConInfo(c);  
  348.     }  
  349. ////////////////////////////////////////////////////  
  350.     /* 
  351.      *测试函数main 
  352.      */  
  353.     public static void main(String[] argvs)  
  354.     {  
  355.         VectorPool pool = new VectorPool();  
  356.         Connection con = null;  
  357.         boolean flag = pool.start("jdbc:mysql://localhost/finance","root","");  
  358.         int cnt = 10000;//1万次  
  359.         long t0  = Calendar.getInstance().getTimeInMillis();  
  360.         /////////测试选项  
  361.         final boolean tflag = true ;//如为true 为使用连接池  否则直接创建一个新连接。  
  362.         //////////////////////////////////////////////////////////////////////////  
  363.         while(flag){  
  364.           
  365.             con = tflag ? pool.getConnection():pool.newConnection();//;  
  366.             try  
  367.             {     
  368.                 Statement stm = con.createStatement();  
  369.                 ResultSet rev = stm.executeQuery("select * from user");  
  370.                 while(false && rev!=null && rev.next())  
  371.                 {  
  372.                     System.out.println(rev.getString("id"));  
  373.                 }  
  374.                 stm.close();  
  375.             }  
  376.             catch(Exception e)  
  377.             {  
  378.                 e.printStackTrace();  
  379.                   
  380.             }  
  381.         //  if(Math.abs(Math.random())%10<4)  
  382.             if(tflag)//使用完之后要释放,否则会出大问题  
  383.                 pool.freeConnection(con);  
  384.             try{  
  385.                 if(!tflag)  
  386.                     con.close();//释放连接 当不用pool时  
  387.             }  
  388.             catch(Exception exx)  
  389.             {  
  390.                 exx.printStackTrace();  
  391.             }  
  392.             /* 
  393.             try{ 
  394.                 sleep(100); ///间隔时间 
  395.             } 
  396.             catch(Exception ee) 
  397.             { 
  398.                 ee.printStackTrace(); 
  399.             } 
  400.             */  
  401.             //System.out.println("cnt:"+cnt);  
  402.         //  System.out.println("con_Cnt:"+pool.getConCount());  
  403.             if(--cnt<0)  
  404.                 break;  
  405.         }  
  406.         System.out.println("used time:"+(Calendar.getInstance().getTimeInMillis()-t0));  
  407.     }  
  408. }  
  409. /* 
  410.  * 
  411. use the pool; 
  412. cnt:3 
  413. cnt:2 
  414. cnt:1 
  415. cnt:0 
  416. used time:11286 
  417. ---用了11.286秒 
  418. cnt:9 
  419. cnt:8 
  420. cnt:7 
  421. cnt:6 
  422. cnt:5 
  423. cnt:4 
  424. cnt:3 
  425. cnt:2 
  426. cnt:1 
  427. cnt:0 
  428. used time:129376 
  429. 用了129.376秒(多了整整十倍)。 
  430. 再测试一次: 
  431. cnt:1 
  432. cnt:0 
  433. used time:7871  
  434. ---used the pool  7.871秒 
  435. cnt:4 
  436. cnt:3 
  437. cnt:2 
  438. cnt:1 
  439. cnt:0 
  440. used time:100084  
  441. ----create the connection one by one   100.084秒 
  442. */  

 

 

 

第二个实现类:ListPool

 

 

  1. /* 
  2.  * @(#)Pool.java 
  3.  * 
  4.  * 
  5.  * @author  
  6.  * @version 1.00 2010/5/15 
  7.  */  
  8. package mysql;  
  9. import mysql.*;  
  10. import java.sql.*;  
  11. import java.util.*;  
  12. /* 
  13.  *这里将实现ConnectionPool接口 
  14.  */  
  15. public class ListPool extends Thread implements Pool   
  16. {  
  17.     protected final boolean debug = false//是否debug态(如是  输出debug状态信息)  
  18.     protected boolean init = false;//是否已经将setting初始化  
  19.     //timeDiff   一个连接超过此时间未使用过,则需要更新此连接----1小时  
  20.     protected final long timeDiff =  60*60*1000 ;//1小时60分钟,1分钟60秒,1秒1000毫秒  
  21.     protected int lows = 20 ; //连接池的最小空闲连接数  
  22.     protected int maxs = 100 ; //连接池的最大空闲连接数  
  23.     protected int maxc = 100;  
  24.     protected String dbname = null;  
  25.     protected String user = null;  
  26.     protected String psw = null;  
  27.       
  28.     protected Integer conCount = 0//这个是静态的。当前连接数  
  29.     //下面是连接保存的池  
  30.     protected LinkedList<ConInfo> pool = new LinkedList<ConInfo>();  
  31.     public ListPool()   
  32.     {  
  33.     }  
  34.     public void start()  
  35.     {  
  36.           
  37.     }  
  38.     //得到当前连接数  
  39.     protected int getConCount()  
  40.     {  
  41.         return conCount;  
  42.     }  
  43.     /* 
  44.      *设置数据库连接的基本参数 
  45.      */  
  46.     public  synchronized  boolean start(String db,String u,String p)  
  47.     {  
  48.         if(false == init && null != pool)//如果未初始化,且连接池可用  
  49.         {  
  50.             dbname  =   db;  
  51.             user    =   u;  
  52.             psw     =   p;  
  53.             if(test())  
  54.             {  
  55.                 init    =   true;  
  56.                 super.start();   
  57.                 return true;  
  58.             }  
  59.             else return false;  
  60.         }  
  61.         else  
  62.             return false;  
  63.     }  
  64.     public synchronized boolean start(int l,int m,int mc,String db,String u,String p)  
  65.     {  
  66.         if(l<0 || m<0 ||l>=m || m>mc)//0<l<m<=mc  
  67.             return false;  
  68.         if(false == init && null != pool)//如果未初始化,且连接池可用  
  69.         {  
  70.             dbname  =   db;  
  71.             user    =   u;  
  72.             psw     =   p;  
  73.             if(test())  
  74.             {  
  75.                 init    =   true;  
  76.                 lows = l<5?5:l;  //这里允许的最小的值为5  
  77.                 maxs = m<10?10:m; //这里允许的最小的值为10  
  78.                 maxc = mc<20 ?20:mc;//这里允许的连接数  
  79.                 super.start();   
  80.                 return true;  
  81.             }  
  82.             else   
  83.                 return false;  
  84.         }  
  85.         else  
  86.             return false;  
  87.     }  
  88.     /* 
  89.      *从连接池得到一个连接 
  90.      */  
  91.     public synchronized Connection getConnection()  
  92.     {  
  93.           
  94.         if(init)  
  95.         {  
  96.             ConInfo c = getOneConnection();  
  97.             return c!=null?c.con:null;//安全得到一个连接  
  98.         }  
  99.         else  
  100.             return null;  
  101.     }  
  102.     /* 
  103.      *得到一个连接,包含了lastTime信息 
  104.      */  
  105.     protected synchronized ConInfo getOneConnection()  
  106.     {  
  107.         if(pool.size()!=0)  
  108.         {  
  109.             return pool.remove(0);  
  110.         }  
  111.         else //如果连接池为空,创建新的连接  
  112.         {  
  113.             if(debug) System.out.println("new connection!");  
  114.             return newConInfo();  
  115.         }  
  116.     }  
  117.     /* 
  118.      *将一个连接放回到连接池中 
  119.      */  
  120.     public synchronized boolean freeConnection(Connection con)  
  121.     {  
  122.         if(init==false || con == null )//当没有init或者已经close之后 不应该free它进来。  
  123.             return false;  
  124.         ConInfo c =  new ConInfo(con);//调用了ConInfo的构造函数  
  125.         pool.add(c);  
  126.         return true;  
  127.     }  
  128.     /* 
  129.      *将内容清空 
  130.      *且将本连接池对象置为无用状态 
  131.      */  
  132.     public synchronized  boolean close()  
  133.     {  
  134.         if(init)  
  135.         {  
  136.             init = false;  
  137.             for(int i = 0; i <pool.size();i++)  
  138.                 pool.get(i).close();  
  139.             pool.clear();  
  140.             pool    =   null;//将此连接池置为无用状态。如果要新的链接池,重新创建链接池对象  
  141.             dbname  =   null;  
  142.             user    =   null;  
  143.             psw     =   null;  
  144.             return true;  
  145.         }  
  146.         else   
  147.             return false;  
  148.     }  
  149.      
  150. ////////////////////////////////////////////////////////////////  
  151.     /* 
  152.      *下面将是一个一线程执行体,当start连接池服务之后,由它来维护 
  153.      *连接池里面的连接,从而保证他们能被正确的创建、注销 
  154.      * 
  155.      */  
  156.     public void run()  
  157.     {  
  158.         final long sleepTime = 2*1000  ; //2秒   
  159.         final long refreshTime = 10*60*1000//10分钟运行一次。连接是否应该被更新  
  160.         final long lowsCheckTime = 2*1000;//10秒检查一次。最低连接数检查间隔时间  
  161.         final long maxsCheckTime = 60*1000;//1分钟检查一次。最大连接数时间  
  162.         long loop = 0;  
  163.         while(true)  
  164.         {  
  165.             if(loop%refreshTime == 0)  
  166.             {  
  167.                 if(debug) System.out.println("call refresh:"+pool.size());  
  168.                 refreshByTimeDiff();  
  169.             }  
  170.             if(loop%maxsCheckTime == 0)  
  171.             {  
  172.                 if(debug) System.out.println("call toMaxs:"+pool.size());  
  173.                 toMaxs();  
  174.             }  
  175.             if(loop%lowsCheckTime == 0)  
  176.             {  
  177.                 if(debug) System.out.println("conCnt:"+conCount+" call toLows:"+pool.size());  
  178.                 toLows();  
  179.             }  
  180.             loop += sleepTime;//更新loop的时间。  
  181.             try{  
  182.                 sleep(sleepTime);  
  183.             }  
  184.             catch(Exception e){  
  185.                 e.printStackTrace();  
  186.                 stop();  
  187.             }  
  188.               
  189.         }  
  190.           
  191.     }  
  192.     /* 
  193.      *使过小的空闲连接数恢复到lows 
  194.      */  
  195.     protected void toLows()  
  196.     {  
  197.         int size = pool.size();  
  198.         /* 
  199.          *这里要避免直接使用pool.size进行判断 
  200.          *当连接一直被get出去之后,size很难达到lows,故此 
  201.          */  
  202.         for(;size<lows;size++)  
  203.         {  
  204.             if(debug) System.out.println("toLows is running!");  
  205.             ConInfo c =  newConInfo();  
  206.             if(c!=null)  
  207.                 synchronized(pool)  
  208.                 {  
  209.                     pool.add(c);  
  210.                 }  
  211.         }  
  212.     }  
  213.     /* 
  214.      *使过多的空闲连接数恢复到maxs; 
  215.      */  
  216.     protected void toMaxs()  
  217.     {  
  218.         int size = pool.size();  
  219.         for(;size>maxs;size--)  
  220.         {  
  221.             if(debug) System.out.println("toMaxs is running!");  
  222.             try{  
  223.                 getConnection().close();  
  224.                 synchronized(conCount)//这里修改要同步好。  
  225.                 {  
  226.                     conCount --;  
  227.                 }  
  228.             }  
  229.             catch(Exception e)  
  230.             {  
  231.                 e.printStackTrace();  
  232.             }  
  233.         }  
  234.     }  
  235.     /* 
  236.      *查找当前的连接池,找到timeDiff时间内未使用过的连接,删除它们,如果连接数不足,将由toLows补齐 
  237.      *一个危险的线程不安全函数 
  238.      */  
  239.     public void refreshByTimeDiff()  
  240.     {  
  241.         Calendar nowTime = Calendar.getInstance();  
  242.         long now = nowTime.getTimeInMillis();  
  243.         for(int i=0;i<pool.size();i++)  
  244.         {  
  245.             ConInfo c = getOneConnection();  
  246.             if(now  - c.lastTime.getTimeInMillis() >=timeDiff)//删除它们  
  247.             {  
  248.                 if(debug) System.out.println("refresh the pool!,,,,,,,,");  
  249.                 synchronized(pool)//获得pool的锁  
  250.                 {  
  251.                     pool.remove(i).close();//使用了ConInfo中的关闭函数  
  252.                 }  
  253.             }  
  254.         }  
  255.     }  
  256.     /* 
  257.      *一个测试数据库连接是否可用的函数 
  258.      */  
  259.     protected boolean test()  
  260.     {  
  261.         int cnt = 10;  
  262.         Connection c;  
  263.         do{  
  264.             c = newConnection();  
  265.             cnt -- ;  
  266.         }while(c==null && cnt>=0);  
  267.         if(c!=null)  
  268.         {  
  269.             (new ConInfo(c)).close();  
  270.             return true;  
  271.         }  
  272.         else  
  273.             return false;  
  274.               
  275.     }  
  276. ////////////////////////////////////////////////////////////////  
  277.     /* 
  278.      *下面为内置的类,用于表明一个连接最后使用时间 
  279.      */  
  280.     class ConInfo  
  281.     {  
  282.         protected Calendar lastTime;    //连接最后使用时间  
  283.         protected Connection con = null;    //对应的connection  
  284.         public ConInfo(Connection c)  
  285.         {  
  286.             con =   c;  
  287.             lastTime = Calendar.getInstance();  
  288.         }  
  289.         public synchronized void close()  
  290.         {  
  291.             try  
  292.             {  
  293.                 if(con!=null)  
  294.                     con.close();  
  295.                 synchronized(conCount)  
  296.                 {  
  297.                     conCount-=con!=null?1:0;  
  298.                 }  
  299.                 lastTime = null;  
  300.             }  
  301.             catch(Exception e)  
  302.             {  
  303.                 e.printStackTrace();  
  304.             }  
  305.         }  
  306.     }  
  307.     /* 
  308.      *创建一个新的连接 
  309.      */  
  310.     protected  Connection newConnection()  
  311.     {  
  312.         try  
  313.         {  
  314.             Class.forName("com.mysql.jdbc.Driver");  
  315.             int cnt = 0;  
  316.             Connection c = null;  
  317.             synchronized(conCount)  
  318.             {  
  319.                 if(conCount<=maxc)//当连接数没超过既定最大连接数时  
  320.                 do  
  321.                 {  
  322.                     try{  
  323.                     c = DriverManager.getConnection(dbname,user,psw);  
  324.                     }catch(Exception es){c=null;if(debug) System.out.println("create new connection error!");}  
  325.                     cnt++;  
  326.                 }while(null == c  && cnt<3);  
  327.                 conCount+=c!=null?1:0;  
  328.             }  
  329.             return c;//创建一个新的connection  
  330.         }  
  331.         catch(Exception e)  
  332.         {  
  333.             e.printStackTrace();  
  334.             return null;  
  335.         }  
  336.     }  
  337.     /* 
  338.      *得到一个新的连接 
  339.      */  
  340.     protected ConInfo newConInfo()  
  341.     {  
  342.         Connection c = newConnection();  
  343.         if(c==null)  
  344.             return null;  
  345.         return new ConInfo(c);  
  346.     }  
  347. ////////////////////////////////////////////////////  
  348.     /* 
  349.      *测试函数main 
  350.      */  
  351.     public static void main(String[] argvs)  
  352.     {  
  353.         ListPool pool = new ListPool();  
  354.         Connection con = null;  
  355.         boolean flag = pool.start("jdbc:mysql://localhost/finance","root","");  
  356.         int cnt = 10000;//1万次  
  357.         long t0  = Calendar.getInstance().getTimeInMillis();  
  358.         /////////测试选项  
  359.         final boolean tflag = true ;//如为true 为使用连接池  否则直接创建一个新连接。  
  360.         //////////////////////////////////////////////////////////////////////////  
  361.         while(flag){  
  362.           
  363.             con = tflag ? pool.getConnection():pool.newConnection();//;  
  364.             try  
  365.             {     
  366.                 Statement stm = con.createStatement();  
  367.                 ResultSet rev = stm.executeQuery("select * from user");  
  368.                 while(false && rev!=null && rev.next())  
  369.                 {  
  370.                     System.out.println(rev.getString("id"));  
  371.                 }  
  372.                 stm.close();  
  373.             }  
  374.             catch(Exception e)  
  375.             {  
  376.                 e.printStackTrace();  
  377.                   
  378.             }  
  379.         //  if(Math.abs(Math.random())%10<4)  
  380.             if(tflag)//使用完之后要释放,否则会出大问题  
  381.                 pool.freeConnection(con);  
  382.             try{  
  383.                 if(!tflag)  
  384.                     con.close();//释放连接 当不用pool时  
  385.             }  
  386.             catch(Exception exx)  
  387.             {  
  388.                 exx.printStackTrace();  
  389.             }  
  390.             /* 
  391.             try{ 
  392.                 sleep(100); ///间隔时间 
  393.             } 
  394.             catch(Exception ee) 
  395.             { 
  396.                 ee.printStackTrace(); 
  397.             } 
  398.             */  
  399.         //  System.out.println("cnt:"+cnt);  
  400.         //  System.out.println("con_Cnt:"+pool.getConCount());  
  401.             if(--cnt<0)  
  402.                 break;  
  403.         }  
  404.         System.out.println("used time:"+(Calendar.getInstance().getTimeInMillis()-t0));  
  405.     }  
  406. }  
  407. /* 
  408.  * 
  409. use the pool; 
  410. cnt:3 
  411. cnt:2 
  412. cnt:1 
  413. cnt:0 
  414. used time:11286 
  415. ---用了11.286秒 
  416. cnt:9 
  417. cnt:8 
  418. cnt:7 
  419. cnt:6 
  420. cnt:5 
  421. cnt:4 
  422. cnt:3 
  423. cnt:2 
  424. cnt:1 
  425. cnt:0 
  426. used time:129376 
  427. 用了129.376秒(多了整整十倍)。 
  428. -------listPool 
  429. used time:10995 
  430. */  

 

 

 

 

 

一个测试类:testPool

 

  1. /** 
  2.  * @(#)testPool.java 
  3.  * 
  4.  * 
  5.  * @author  
  6.  * @version 1.00 2010/5/15 
  7.  */  
  8. package  mysql;  
  9. import java.sql.*;  
  10. import java.util.*;  
  11. import mysql.*;  
  12. public class testPool extends Thread  
  13. {  
  14.     protected  String dbname = null,  
  15.                         user = null,  
  16.                         psw  = null;  
  17.     Pool pool= null;  
  18.     boolean flag = true;  
  19.     public testPool(Pool p,boolean f,String d,String u,String pw)   
  20.     {  
  21.         pool = p;  
  22.         flag = f;  
  23.         dbname = d;  
  24.         user = u;  
  25.         psw = pw;  
  26.     }  
  27.     public void start(int n)  
  28.     {  
  29.         while(n-->0)  
  30.         {  
  31.             super.start();  
  32.         }  
  33.     }  
  34.     public void run()  
  35.     {  
  36.         long id = this.getId();  
  37.         Connection con = null;  
  38.         int cnt = 100;//1万次  
  39.         long t0  = Calendar.getInstance().getTimeInMillis();  
  40.         /////////测试选项  
  41.         final boolean tflag = true ;//如为true 为使用连接池  否则直接创建一个新连接。  
  42.         //////////////////////////////////////////////////////////////////////////  
  43.         while(flag){  
  44.           
  45.             con = tflag ? pool.getConnection():newConnection();//;  
  46.             if(con == nullcontinue;  
  47.             try  
  48.             {     
  49.                 Statement stm = con.createStatement();  
  50.                 ResultSet rev = stm.executeQuery("select * from user");  
  51.                 while(false && rev!=null && rev.next())  
  52.                 {  
  53.                     System.out.println(rev.getString("id"));  
  54.                 }  
  55.                 stm.close();  
  56.             }  
  57.             catch(Exception e)  
  58.             {  
  59.                 e.printStackTrace();  
  60.                   
  61.             }  
  62.         //  if(Math.abs(Math.random())%10<4)  
  63.             if(tflag)//使用完之后要释放,否则会出大问题  
  64.                 pool.freeConnection(con);  
  65.             try{  
  66.                 if(!tflag)  
  67.                     con.close();//释放连接 当不用pool时  
  68.             }  
  69.             catch(Exception exx)  
  70.             {  
  71.                 exx.printStackTrace();  
  72.             }  
  73.             /* 
  74.             try{ 
  75.                 sleep(100); ///间隔时间 
  76.             } 
  77.             catch(Exception ee) 
  78.             { 
  79.                 ee.printStackTrace(); 
  80.             } 
  81.             */  
  82.         //  System.out.println("threadId:"+id+"  cnt:"+cnt);  
  83.            //System.out.println("con_Cnt:"+((Pool)pool).getConCount());  
  84.             if(--cnt<0)  
  85.                 break;  
  86.         }  
  87.         System.out.println("used time:"+(Calendar.getInstance().getTimeInMillis()-t0));  
  88.     }  
  89.     public Connection newConnection()  
  90.     {  
  91.         try  
  92.         {  
  93.             Class.forName("com.mysql.jdbc.Driver");  
  94.             int cnt = 0;  
  95.             Connection c = null;  
  96.             do  
  97.             {  
  98.                 c = DriverManager.getConnection(dbname,user,psw);  
  99.                 cnt++;  
  100.             }while(null == c && cnt<15);  
  101.             if(null == c)  
  102.                 return null;  
  103.             else  
  104.                 return c;//创建一个新的connection  
  105.         }  
  106.         catch(Exception e)  
  107.         {  
  108.             e.printStackTrace();  
  109.             return null;  
  110.         }  
  111.     }  
  112.     public static void main(String argv[])  
  113.     {  
  114.         Pool pool = null;  
  115.         boolean who = true;  
  116.         pool = who ? new VectorPool() : new ListPool();  
  117.         boolean flag = pool.start(20,30,100,"jdbc:mysql://localhost/finance","root","");  
  118.         int cnt = 100;  
  119.         while(cnt-->0)  
  120.         {  
  121.             testPool p = new testPool(pool,flag,"jdbc:mysql://localhost/finance","root","");  
  122.             p.start();  
  123.         }     
  124.     
  125.     }  
  126.       
  127. }  
  128. /* 
  129.  *测试结果表明,当100*100时,Pool要略优于ListPool(差异不大,如下) 
  130.  * 
  131. Pool: 
  132. used time:4967 
  133. used time:4997 
  134. used time:5017 
  135. used time:5218 
  136. used time:5558 
  137. used time:4937 
  138. used time:4977 
  139. used time:5107 
  140. used time:5378 
  141. used time:5368 
  142. used time:5408 
  143. 2: 
  144. used time:5779 
  145. used time:6049 
  146. used time:6269 
  147. used time:6269 
  148. used time:6209 
  149. used time:6009 
  150. ListPool 
  151. used time:5788 
  152. used time:6148 
  153. used time:5589 
  154. used time:5819 
  155. used time:5619 
  156. used time:6089 
  157. used time:5558 
  158. used time:6029 
  159. used time:5629 
  160. 2 
  161. used time:5158 
  162. used time:5188 
  163. used time:5808 
  164. used time:5117 
  165. used time:5648 
  166. used time:5718 
  167. used time:5668 
  168. used time:5868 
  169. used time:5908 
  170. used time:5948 
  171. used time:5958 
  172. used time:5828 
  173. used time:5969 
  174. used time:5979 
  175. used time:6329 
  176. used time:6089 
  177.  */  

 

posted on 2012-06-05 08:19  ycty  阅读(589)  评论(0编辑  收藏  举报