多线程情况下创建连接池

JAVA数据库连接池实现
博客分类:
• 数据库连接池
JAVA数据库连接池连接池原理连接池实现JAVA连接池
连接池的管理用了了享元模式,这里对连接池进行简单设计。
一、设计思路
1.连接池配置属性DBbean:里面存放可以配置的一些属性
2.连接池接口IConnectionPool:里面定义一些基本的获取连接的一些方法
3.接口实现ConnectionPool:对上面操作进行实现,并加入一些其他方法
4.连接池管理ConnectionPoolManager:管理所有的不同的连接池,所有的连接都能通过这里进行获得连接
5.另外还有几个测试类,和连接信息模拟的类,这里就不进行xml 和配置文件信息的读取了
Java代码


1.  package pool;  
2.  /** 
3.   * 这是外部可以配置的连接池属性 
4.   * 可以允许外部配置,拥有默认值 
5.   * @author Ran 
6.   * 
7.   */  
8.  public class DBbean {  
9.      // 连接池属性  
10.     private String driverName;  
11.     private String url;  
12.     private String userName;  
13.     private String password;  
14.     // 连接池名字  
15.     private String poolName;  
16.     private int minConnections = 1; // 空闲池,最小连接数  
17.     private int maxConnections = 10; // 空闲池,最大连接数  
18.       
19.     private int initConnections = 5;// 初始化连接数  
20.       
21.     private long connTimeOut = 1000;// 重复获得连接的频率  
22.       
23.     private int maxActiveConnections = 100;// 最大允许的连接数,和数据库对应  
24.       
25.     private long connectionTimeOut = 1000*60*20;// 连接超时时间,默认20分钟  
26.       
27.     private boolean isCurrentConnection = true; // 是否获得当前连接,默认true  
28.       
29.     private boolean isCheakPool = true; // 是否定时检查连接池  
30.     private long lazyCheck = 1000*60*60;// 延迟多少时间后开始 检查  
31.     private long periodCheck = 1000*60*60;// 检查频率  
32.       
33.       
34.       
35.     public DBbean(String driverName, String url, String userName,  
36.             String password, String poolName) {  
37.         super();  
38.         this.driverName = driverName;  
39.         this.url = url;  
40.         this.userName = userName;  
41.         this.password = password;  
42.         this.poolName = poolName;  
43.     }  
44.     public DBbean() {  
45.     }  
46.     public String getDriverName() {  
47.         if(driverName == null){  
48.             driverName = this.getDriverName()+"_"+this.getUrl();  
49.         }  
50.         return driverName;  
51.     }  
52.     public void setDriverName(String driverName) {  
53.         this.driverName = driverName;  
54.     }  
55.     public String getUrl() {  
56.         return url;  
57.     }  
58.     public void setUrl(String url) {  
59.         this.url = url;  
60.     }  
61.     public String getUserName() {  
62.         return userName;  
63.     }  
64.     public void setUserName(String userName) {  
65.         this.userName = userName;  
66.     }  
67.     public String getPassword() {  
68.         return password;  
69.     }  
70.     public void setPassword(String password) {  
71.         this.password = password;  
72.     }  
73.     public String getPoolName() {  
74.         return poolName;  
75.     }  
76.     public void setPoolName(String poolName) {  
77.         this.poolName = poolName;  
78.     }  
79.     public int getMinConnections() {  
80.         return minConnections;  
81.     }  
82.     public void setMinConnections(int minConnections) {  
83.         this.minConnections = minConnections;  
84.     }  
85.     public int getMaxConnections() {  
86.         return maxConnections;  
87.     }  
88.     public void setMaxConnections(int maxConnections) {  
89.         this.maxConnections = maxConnections;  
90.     }  
91.     public int getInitConnections() {  
92.         return initConnections;  
93.     }  
94.     public void setInitConnections(int initConnections) {  
95.         this.initConnections = initConnections;  
96.     }  
97.   
98.     public int getMaxActiveConnections() {  
99.         return maxActiveConnections;  
100.        }  
101.        public void setMaxActiveConnections(int maxActiveConnections) {  
102.            this.maxActiveConnections = maxActiveConnections;  
103.        }  
104.        public long getConnTimeOut() {  
105.            return connTimeOut;  
106.        }  
107.        public void setConnTimeOut(long connTimeOut) {  
108.            this.connTimeOut = connTimeOut;  
109.        }  
110.        public long getConnectionTimeOut() {  
111.            return connectionTimeOut;  
112.        }  
113.        public void setConnectionTimeOut(long connectionTimeOut) {  
114.            this.connectionTimeOut = connectionTimeOut;  
115.        }  
116.        public boolean isCurrentConnection() {  
117.            return isCurrentConnection;  
118.        }  
119.        public void setCurrentConnection(boolean isCurrentConnection) {  
120.            this.isCurrentConnection = isCurrentConnection;  
121.        }  
122.        public long getLazyCheck() {  
123.            return lazyCheck;  
124.        }  
125.        public void setLazyCheck(long lazyCheck) {  
126.            this.lazyCheck = lazyCheck;  
127.        }  
128.        public long getPeriodCheck() {  
129.            return periodCheck;  
130.        }  
131.        public void setPeriodCheck(long periodCheck) {  
132.            this.periodCheck = periodCheck;  
133.        }  
134.        public boolean isCheakPool() {  
135.            return isCheakPool;  
136.        }  
137.        public void setCheakPool(boolean isCheakPool) {  
138.            this.isCheakPool = isCheakPool;  
139.        }  
140.          
141.          
142.          
143.    }  

Java代码


1.  package pool;  
2.    
3.  import java.sql.Connection;  
4.  import java.sql.SQLException;  
5.    
6.  public interface IConnectionPool {  
7.      // 获得连接  
8.      public Connection  getConnection();  
9.      // 获得当前连接  
10.     public Connection getCurrentConnecton();  
11.     // 回收连接  
12.     public void releaseConn(Connection conn) throws SQLException;  
13.     // 销毁清空  
14.     public void destroy();  
15.     // 连接池是活动状态  
16.     public boolean isActive();  
17.     // 定时器,检查连接池  
18.     public void cheackPool();  
19. }  

Java代码


1.  package pool;  
2.    
3.  import java.sql.Connection;  
4.  import java.sql.DriverManager;  
5.  import java.sql.SQLException;  
6.  import java.util.List;  
7.  import java.util.Timer;  
8.  import java.util.TimerTask;  
9.  import java.util.Vector;  
10.   
11. public class ConnectionPool implements IConnectionPool {  
12.     // 连接池配置属性  
13.     private DBbean dbBean;  
14.     private boolean isActive = false; // 连接池活动状态  
15.     private int contActive = 0;// 记录创建的总的连接数  
16.       
17.     // 空闲连接  
18.     private List<Connection> freeConnection = new Vector<Connection>();  
19.     // 活动连接  
20.     private List<Connection> activeConnection = new Vector<Connection>();  
21.     // 将线程和连接绑定,保证事务能统一执行  
22.     private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();  
23.       
24.     public ConnectionPool(DBbean dbBean) {  
25.         super();  
26.         this.dbBean = dbBean;  
27.         init();  
28.         cheackPool();  
29.     }  
30.   
31.     // 初始化  
32.     public void init() {  
33.         try {  
34.             Class.forName(dbBean.getDriverName());  
35.             for (int i = 0; i < dbBean.getInitConnections(); i++) {  
36.                 Connection conn;  
37.                 conn = newConnection();  
38.                 // 初始化最小连接数  
39.                 if (conn != null) {  
40.                     freeConnection.add(conn);  
41.                     contActive++;  
42.                 }  
43.             }  
44.             isActive = true;  
45.         } catch (ClassNotFoundException e) {  
46.             e.printStackTrace();  
47.         } catch (SQLException e) {  
48.             e.printStackTrace();  
49.         }  
50.     }  
51.       
52.     // 获得当前连接  
53.     public Connection getCurrentConnecton(){  
54.         // 默认线程里面取  
55.         Connection conn = threadLocal.get();  
56.         if(!isValid(conn)){  
57.             conn = getConnection();  
58.         }  
59.         return conn;  
60.     }  
61.   
62.     // 获得连接  
63.     public synchronized Connection getConnection() {  
64.         Connection conn = null;  
65.         try {  
66.             // 判断是否超过最大连接数限制  
67.             if(contActive < this.dbBean.getMaxActiveConnections()){  
68.                 if (freeConnection.size() > 0) {  
69.                     conn = freeConnection.get(0);  
70.                     if (conn != null) {  
71.                         threadLocal.set(conn);  
72.                     }  
73.                     freeConnection.remove(0);  
74.                 } else {  
75.                     conn = newConnection();  
76.                 }  
77.                   
78.             }else{  
79.                 // 继续获得连接,直到从新获得连接  
80.                 wait(this.dbBean.getConnTimeOut());  
81.                 conn = getConnection();  
82.             }  
83.             if (isValid(conn)) {  
84.                 activeConnection.add(conn);  
85.                 contActive ++;  
86.             }  
87.         } catch (SQLException e) {  
88.             e.printStackTrace();  
89.         } catch (ClassNotFoundException e) {  
90.             e.printStackTrace();  
91.         } catch (InterruptedException e) {  
92.             e.printStackTrace();  
93.         }  
94.         return conn;  
95.     }  
96.   
97.     // 获得新连接  
98.     private synchronized Connection newConnection()  
99.             throws ClassNotFoundException, SQLException {  
100.            Connection conn = null;  
101.            if (dbBean != null) {  
102.                Class.forName(dbBean.getDriverName());  
103.                conn = DriverManager.getConnection(dbBean.getUrl(),  
104.                        dbBean.getUserName(), dbBean.getPassword());  
105.            }  
106.            return conn;  
107.        }  
108.      
109.        // 释放连接  
110.        public synchronized void releaseConn(Connection conn) throws SQLException {  
111.            if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) {  
112.                freeConnection.add(conn);  
113.                activeConnection.remove(conn);  
114.                contActive --;  
115.                threadLocal.remove();  
116.                // 唤醒所有正待等待的线程,去抢连接  
117.                notifyAll();  
118.            }  
119.        }  
120.      
121.        // 判断连接是否可用  
122.        private boolean isValid(Connection conn) {  
123.            try {  
124.                if (conn == null || conn.isClosed()) {  
125.                    return false;  
126.                }  
127.            } catch (SQLException e) {  
128.                e.printStackTrace();  
129.            }  
130.            return true;  
131.        }  
132.      
133.        // 销毁连接池  
134.        public synchronized void destroy() {  
135.            for (Connection conn : freeConnection) {  
136.                try {  
137.                    if (isValid(conn)) {  
138.                        conn.close();  
139.                    }  
140.                } catch (SQLException e) {  
141.                    e.printStackTrace();  
142.                }  
143.            }  
144.            for (Connection conn : activeConnection) {  
145.                try {  
146.                    if (isValid(conn)) {  
147.                        conn.close();  
148.                    }  
149.                } catch (SQLException e) {  
150.                    e.printStackTrace();  
151.                }  
152.            }  
153.            isActive = false;  
154.            contActive = 0;  
155.        }  
156.      
157.        // 连接池状态  
158.        @Override  
159.        public boolean isActive() {  
160.            return isActive;  
161.        }  
162.          
163.        // 定时检查连接池情况  
164.        @Override  
165.        public void cheackPool() {  
166.            if(dbBean.isCheakPool()){  
167.                new Timer().schedule(new TimerTask() {  
168.                @Override  
169.                public void run() {  
170.                // 1.对线程里面的连接状态  
171.                // 2.连接池最小 最大连接数  
172.                // 3.其他状态进行检查,因为这里还需要写几个线程管理的类,暂时就不添加了  
173.                System.out.println("空线池连接数:"+freeConnection.size());  
174.                System.out.println("活动连接数::"+activeConnection.size());  
175.                System.out.println("总的连接数:"+contActive);  
176.                    }  
177.                },dbBean.getLazyCheck(),dbBean.getPeriodCheck());  
178.            }  
179.        }  
180.    }  

Java代码
1. package pool;
2.
3. import java.sql.Connection;
4. import java.sql.SQLException;
5. import java.util.Hashtable;
6. /**
7. * 连接管理类
8. * @author Ran
9. *
10. */
11. public class ConnectionPoolManager {
12.
13.
14. // 连接池存放
15. public Hashtable


1.  package pool;  
2.    
3.  import java.sql.Connection;  
4.  /** 
5.   * 模拟线程启动,去获得连接 
6.   * @author Ran 
7.   * 
8.   */  
9.  public class ThreadConnection implements Runnable{  
10.     private IConnectionPool pool;  
11.     @Override  
12.     public void run() {  
13.         pool = ConnectionPoolManager.getInstance().getPool("testPool");  
14.     }  
15.       
16.     public Connection getConnection(){  
17.         Connection conn = null;  
18.         if(pool != null && pool.isActive()){  
19.             conn = pool.getConnection();  
20.         }  
21.         return conn;  
22.     }  
23.       
24.     public Connection getCurrentConnection(){  
25.         Connection conn = null;  
26.         if(pool != null && pool.isActive()){  
27.             conn = pool.getCurrentConnecton();  
28.         }  
29.         return conn;  
30.     }  
31. }  

Java代码


1.  package pool;    
5.  public class Client {  
6.      public static void main(String[] args) throws InterruptedException {  
7.          // 初始化连接池  
8.          Thread t = init();  
9.          t.start();  
10.         t.join();  
11.           
12.         ThreadConnection a = new ThreadConnection();  
13.         ThreadConnection b = new ThreadConnection();  
14.         ThreadConnection c = new ThreadConnection();  
15.         Thread t1 = new Thread(a);  
16.         Thread t2 = new Thread(b);  
17.         Thread t3 = new Thread(c);  
18.           
19.           
20.         // 设置优先级,先让初始化执行,模拟 线程池 先启动  
21.         // 这里仅仅表面控制了,因为即使t 线程先启动,也不能保证pool 初始化完成,为了简单模拟,这里先这样写了  
22.         t1.setPriority(10);  
23.         t2.setPriority(10);  
24.         t3.setPriority(10);  
25.         t1.start();  
26.         t2.start();  
27.         t3.start();  
28.           
29.         System.out.println("线程A-> "+a.getConnection());  
30.         System.out.println("线程B-> "+b.getConnection());  
31.         System.out.println("线程C-> "+c.getConnection());  
32.     }  
33.   
34.     // 初始化  
35.     public static Thread init() {  
36.         Thread t = new Thread(new Runnable() {  
37.             @Override  
38.             public void run() {  
39.                 IConnectionPool  pool = initPool();  
40.                 while(pool == null || !pool.isActive()){  
41.                     pool = initPool();  
42.                 }  
43.             }  
44.         });  
45.         return t;  
46.     }  
47.       
48.     public static IConnectionPool initPool(){  
49.         return ConnectionPoolManager.getInstance().getPool("testPool");  
50.     }  
51.   
52. }  

小结 :
1.连接池诞生原因是,如果每次都从数据库获得连接,时间比较长,因此我们提前做建立一些连接,放在连接池里面,每次都从里面取
2.上面仅仅写了连接池基本原理,关于多线程下连接池的管理没写,后面对多线程操作熟练了添加吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值