`
xuyongping
  • 浏览: 123608 次
  • 性别: Icon_minigender_1
  • 来自: 部落格
社区版块
存档分类
最新评论

java 数据可连接池的使用。

阅读更多
1.package com.xiaobian;   
2.  
3./**  
4. * 数据库连接池管理类  
5. */  
6.import java.io.*;   
7.import java.sql.*;   
8.import java.util.*;   
9.import java.util.Date;   
10.  
11./**  
12. * 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接池的  
13. * 访问.客户程序可以调用getInstance()方法访问本类的唯一实例  
14. */  
15.public class DBConnectionManager {   
16.       
17.    public static void main(String[] args) {   
18.        DBConnectionManager connectionManager = DBConnectionManager.getInstance();   
19.           
20.        Connection conn =  connectionManager.getConnection("idb");   
21.            try {   
22.                Thread.sleep(10);   
23.            } catch (InterruptedException e) {   
24.                // TODO Auto-generated catch block   
25.                e.printStackTrace();   
26.            }   
27.        Connection conn1 =  connectionManager.getConnection("idb");   
28.        Connection conn2 =  connectionManager.getConnection("idb");   
29.        Connection conn3 =  connectionManager.getConnection("idb");   
30.        Connection conn4 =  connectionManager.getConnection("idb");   
31.        Connection conn5 =  connectionManager.getConnection("idb");   
32.        connectionManager.freeConnection("idb", conn);   
33.        connectionManager.freeConnection("idb", conn1);   
34.        connectionManager.freeConnection("idb", conn2);   
35.        connectionManager.freeConnection("idb", conn3);   
36.        connectionManager.freeConnection("idb", conn4);   
37.        connectionManager.freeConnection("idb", conn5);   
38.        Connection conn6 = connectionManager.getConnection("idb");   
39.        Connection conn7 = connectionManager.getConnection("idb");   
40.        System.out.println(" conn6 == "+conn6 +" conn7 == "+conn7);   
41.           
42.    }   
43.  
44.       
45.    static private DBConnectionManager instance; // 唯一实例   
46.  
47.    static private int clients; //   
48.  
49.    private Vector drivers = new Vector();   
50.  
51.    private PrintWriter log;   
52.  
53.    private Hashtable pools = new Hashtable();   
54.  
55.    /**  
56.     * 返回唯一实例.如果是第一次调用此方法,则创建实例  
57.     *   
58.     * @return DBConnectionManager 唯一实例  
59.     */  
60.    static synchronized public DBConnectionManager getInstance() {   
61.        if (instance == null) {   
62.            instance = new DBConnectionManager();   
63.        }   
64.        clients++;   
65.        return instance;   
66.    }   
67.  
68.    /**  
69.     * 建构私有函数以防止其它对象创建本类实例  
70.     */  
71.    private DBConnectionManager() {   
72.        init();   
73.    }   
74.  
75.    /**  
76.     * 将连接对象返回给由名字指定的连接池  
77.     *   
78.     * @param name  
79.     *            在属性文件中定义的连接池名字  
80.     * @param con  
81.     *            连接对象  
82.     */  
83.    public void freeConnection(String name, Connection con) {   
84.        DBConnectionPool pool = (DBConnectionPool) pools.get(name);   
85.        if (pool != null) {   
86.            pool.freeConnection(con);   
87.        }   
88.    }   
89.  
90.    /**  
91.     * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 限制,则创建并返回新连接  
92.     *   
93.     * @param name  
94.     *            在属性文件中定义的连接池名字  
95.     * @return Connection 可用连接或null  
96.     */  
97.    public Connection getConnection(String name) {   
98.        DBConnectionPool pool = (DBConnectionPool) pools.get(name);   
99.        //System.out.println(" pool == "+pool);   
100.        if (pool != null) {   
101.            return pool.getConnection();   
102.        }   
103.        return null;   
104.    }   
105.  
106.    /**  
107.     * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.  
108.     *   
109.     * @param name  
110.     *            连接池名字  
111.     * @param time  
112.     *            以毫秒计的等待时间  
113.     * @return Connection 可用连接或null  
114.     */  
115.    public Connection getConnection(String name, long time) {   
116.        DBConnectionPool pool = (DBConnectionPool) pools.get(name);   
117.        if (pool != null) {   
118.            return pool.getConnection(time);   
119.        }   
120.        return null;   
121.    }   
122.  
123.    /**  
124.     * 关闭所有连接,撤销驱动程序的注册  
125.     */  
126.    public synchronized void release() {   
127.        // 等待直到最后一个客户程序调用   
128.        if (--clients != 0) {   
129.            return;   
130.        }   
131.        Enumeration allPools = pools.elements();   
132.        while (allPools.hasMoreElements()) {   
133.            DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();   
134.            pool.release();   
135.        }   
136.        Enumeration allDrivers = drivers.elements();   
137.        while (allDrivers.hasMoreElements()) {   
138.            Driver driver = (Driver) allDrivers.nextElement();   
139.            try {   
140.                DriverManager.deregisterDriver(driver);   
141.                log("撤销JDBC驱动程序 " + driver.getClass().getName() + "的注册");   
142.            } catch (SQLException e) {   
143.                log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());   
144.            }   
145.        }   
146.    }   
147.  
148.    /**  
149.     * 根据指定属性创建连接池实例.  
150.     *   
151.     * @param props  
152.     *            连接池属性  
153.     */  
154.    private void createPools(Properties props) {   
155.        Enumeration propNames = props.propertyNames();   
156.        while (propNames.hasMoreElements()) {   
157.            String name = (String) propNames.nextElement();   
158.            if (name.endsWith(".url")) {   
159.                String poolName = name.substring(0, name.lastIndexOf("."));   
160.                //System.out.println(" poolName ||"+poolName+"|");   
161.                String url = props.getProperty(poolName + ".url");   
162.                if (url == null) {   
163.                    log("没有为连接池" + poolName + "指定URL");   
164.                    continue;   
165.                }   
166.                String user = props.getProperty(poolName + ".user");   
167.                String password = props.getProperty(poolName + ".password");   
168.                String maxconn = props.getProperty(poolName + ".maxconn", "0");   
169.                int max;   
170.                try {   
171.                    max = Integer.valueOf(maxconn).intValue();   
172.                } catch (NumberFormatException e) {   
173.                    log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName);   
174.                    max = 0;   
175.                }   
176.                DBConnectionPool pool = new DBConnectionPool(poolName, url,   
177.                        user, password, max);   
178.                pools.put(poolName, pool);   
179.                log("成功创建连接池" + poolName);   
180.            }   
181.        }   
182.    }   
183.  
184.    // --------------------------------------------------------------------------------   
185.  
186.    /**  
187.     * 读取属性完成初始化  
188.     */  
189.    private void init() {   
190.           
191.        InputStream fileinputstream = null;   
192.        try {   
193.            fileinputstream = new FileInputStream("./src/db.properties");   
194.        } catch (FileNotFoundException e1) {   
195.            e1.printStackTrace();   
196.        }   
197.        //BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(fileinputstream));   
198.  
199.        //InputStream is = getClass().getResourceAsStream("D:/workspace/UmessageSms/src/db.properties");   
200.        Properties dbProps = new Properties();   
201.        try {   
202.            dbProps.load(fileinputstream);   
203.        } catch (Exception e) {   
204.            e.printStackTrace();   
205.            System.err.println("不能读取属性文件. "  
206.                    + "请确保db.properties在CLASSPATH指定的路径中");   
207.            return;   
208.        }   
209.        String logFile = dbProps.getProperty("logfile",   
210.                "DBConnectionManager.log");   
211.           
212.        //System.out.println(dbProps.getProperty("logfile"));   
213.        try {   
214.            log = new PrintWriter(new FileWriter(logFile, true), true);   
215.        } catch (IOException e) {   
216.            System.err.println("无法打开日志文件: " + logFile);   
217.            log = new PrintWriter(System.err);   
218.        }   
219.        loadDrivers(dbProps);   
220.        createPools(dbProps);   
221.    }   
222.  
223.    /**  
224.     * 装载和注册所有JDBC驱动程序  
225.     *   
226.     * @param props  
227.     *            属性  
228.     */  
229.    private void loadDrivers(Properties props) {   
230.        String driverClasses = props.getProperty("drivers");   
231.        StringTokenizer st = new StringTokenizer(driverClasses);   
232.        while (st.hasMoreElements()) {   
233.            String driverClassName = st.nextToken().trim();   
234.            try {   
235.                Driver driver = (Driver) Class.forName(driverClassName)   
236.                        .newInstance();   
237.                DriverManager.registerDriver(driver);   
238.                drivers.addElement(driver);   
239.                log("成功注册JDBC驱动程序" + driverClassName);   
240.            } catch (Exception e) {   
241.                log("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " + e);   
242.            }   
243.        }   
244.    }   
245.  
246.    /**  
247.     * 将文本信息写入日志文件  
248.     */  
249.    private void log(String msg) {   
250.        log.println(new Date() + ": " + msg);   
251.    }   
252.  
253.    /**  
254.     * 将文本信息与异常写入日志文件  
255.     */  
256.    private void log(Throwable e, String msg) {   
257.        log.println(new Date() + ": " + msg);   
258.        e.printStackTrace(log);   
259.    }   
260.  
261.    /** ************************************************************* */  
262.    /** ********************内部类DBConnectionPool******************** */  
263.    /** ************************************************************* */  
264.    /**  
265.     * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.  
266.     */  
267.    class DBConnectionPool {   
268.        private int checkedOut; // 当前连接数   
269.  
270.        private Vector freeConnections = new Vector(); // 保存所有可用连接   
271.  
272.        private int maxConn; // 此连接池允许建立的最大连接数   
273.  
274.        private String name; // 连接池名字   
275.  
276.        private String password; // 密码或null   
277.  
278.        private String URL; // 数据库的JDBC URL   
279.  
280.        private String user; // 数据库账号或null   
281.  
282.        /**  
283.         * 创建新的连接池  
284.         *   
285.         * @param name  
286.         *            连接池名字  
287.         * @param URL  
288.         *            数据库的JDBC URL  
289.         * @param user  
290.         *            数据库帐号或 null  
291.         * @param password  
292.         *            密码或 null  
293.         * @param maxConn  
294.         *            此连接池允许建立的最大连接数  
295.         */  
296.        public DBConnectionPool(String name, String URL, String user,   
297.                String password, int maxConn) {   
298.            this.name = name;   
299.            this.URL = URL;   
300.            this.user = user;   
301.            this.password = password;   
302.            this.maxConn = maxConn;   
303.        }   
304.  
305.        /**  
306.         * 将不再使用的连接返回给连接池  
307.         *   
308.         * @param con  
309.         *            客户程序释放的连接  
310.         */  
311.        public synchronized void freeConnection(Connection con) {   
312.            // 将指定连接加入到向量末尾   
313.            freeConnections.addElement(con);   
314.            checkedOut--;   
315.            notifyAll(); // 删除等待队列中的所有线程   
316.        }   
317.  
318.        /**  
319.         * 从连接池获得一个可用连接.如果没有空闲的连接且当前连接数小于最大连接  
320.         * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之, 然后递归调用自己以尝试新的可用连接.  
321.         */  
322.        public synchronized Connection getConnection() {   
323.            Connection con = null;   
324.            //System.out.println(" freeConnections.size() "+freeConnections.size());   
325.            if (freeConnections.size() > 0) {   
326.                // 获取向量中第一个可用连接   
327.                con = (Connection) freeConnections.firstElement();   
328.                freeConnections.removeElementAt(0);   
329.                try {   
330.                    if (con.isClosed()) {   
331.                        log("从连接池" + name + "删除一个无效连接");   
332.                        // 递归调用自己,尝试再次获取可用连接   
333.                        con = getConnection();   
334.                    }   
335.                } catch (SQLException e) {   
336.                    log("从连接池" + name + "删除一个无效连接");   
337.                    // 递归调用自己,尝试再次获取可用连接   
338.                    con = getConnection();   
339.                }   
340.            } else if (maxConn == 0 || checkedOut < maxConn) {   
341.                con = newConnection();   
342.            }   
343.            if (con != null) {   
344.                checkedOut++;   
345.            }   
346.            System.out.println("con == "+con);   
347.            return con;   
348.        }   
349.  
350.        /**  
351.         * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间 参见前一个getConnection()方法.  
352.         *   
353.         * @param timeout  
354.         *            以毫秒计的等待时间限制  
355.         */  
356.        public synchronized Connection getConnection(long timeout) {   
357.            long startTime = new Date().getTime();   
358.            Connection con;   
359.            while ((con = getConnection()) == null) {   
360.                try {   
361.                    wait(timeout);   
362.                } catch (InterruptedException e) {   
363.                }   
364.                if ((new Date().getTime() - startTime) >= timeout) {   
365.                    // wait()返回的原因是超时   
366.                    return null;   
367.                }   
368.            }   
369.            return con;   
370.        }   
371.  
372.        /**  
373.         * 关闭所有连接  
374.         */  
375.        public synchronized void release() {   
376.            Enumeration allConnections = freeConnections.elements();   
377.            while (allConnections.hasMoreElements()) {   
378.                Connection con = (Connection) allConnections.nextElement();   
379.                try {   
380.                    con.close();   
381.                    log("关闭连接池" + name + "中的一个连接");   
382.                } catch (SQLException e) {   
383.                    log(e, "无法关闭连接池" + name + "中的连接");   
384.                }   
385.            }   
386.            freeConnections.removeAllElements();   
387.        }   
388.  
389.        /**  
390.         * 创建新的连接  
391.         */  
392.        private Connection newConnection() {   
393.            Connection con = null;   
394.            try {   
395.                if (user == null) {   
396.                    con = DriverManager.getConnection(URL);   
397.                } else {   
398.                    con = DriverManager.getConnection(URL, user, password);   
399.                }   
400.                log("连接池" + name + "创建一个新的连接");   
401.            } catch (SQLException e) {   
402.                log(e, "无法创建下列URL的连接: " + URL);   
403.                return null;   
404.            }   
405.            return con;   
406.        }   
407.    }   
408.} 











转载自:http://xiaobian.iteye.com/blog/111797
分享到:
评论

相关推荐

    java socket连接池 实现

    Java Socket 连接池实现是提高网络应用性能和效率的关键技术之一。在高并发的网络环境中,频繁地创建和销毁Socket连接会导致大量的系统资源浪费,影响整体性能。为了解决这个问题,开发人员通常会使用连接池来管理和...

    java常用数据源连接池配置

    数据源(DataSource)是Java中用于获取数据库连接的标准接口,而连接池则是一种管理数据库连接的机制,它预先创建一定数量的数据库连接并将它们存储在一个池中,供应用程序重复使用。这种方式可以显著减少创建和销毁...

    JAVA 使用数据库连接池连接Oracle数据库全代码

    ### JAVA 使用数据库连接池连接Oracle数据库全代码解析 #### 一、概述 本文将详细介绍如何在Java项目中使用Apache DBCP(Database Connection Pool)来连接Oracle数据库,并提供完整的示例代码。通过这种方式,我们...

    java数据连接池通用类(范例)

    这个"java数据连接池通用类(范例)"可能是为了提供一个可以适用于多种连接池实现的通用模板,方便开发者快速集成和管理数据库连接。 首先,我们要理解数据连接池的工作原理。当应用程序启动时,连接池会预先初始化...

    java两种连接池的使用举例

    本篇文章将详细讲解两种常用的Java数据库连接池——C3P0和HikariCP的配置与使用方法。 首先,我们先来理解一下数据库连接池的基本原理。数据库连接池在应用程序启动时创建一定数量的数据库连接,这些连接在应用程序...

    Java连接SAP系统所用的JCo连接池的配置和使用

    "Java连接SAP系统所用的JCo连接池的配置和使用" Java连接SAP系统所用的JCo连接池的配置和使用是指在Java应用程序中使用JCo连接池来连接SAP R3系统的技术。JCo(Java Connector)是SAP提供的一种Java API,用于连接...

    Mongodb连接池for java

    了解并正确使用MongoDB的Java连接池对于提高应用程序性能和稳定性至关重要,特别是在高并发的Web应用或大数据处理项目中。因此,深入理解连接池的工作原理和配置方法,对于任何MongoDB Java开发者来说都是必要的技能...

    java socket连接池

    在Java中,可以使用第三方库如Apache Commons Pool或者HikariCP来实现Socket连接池。这些库提供了完善的连接池管理功能,包括连接的创建、分配、回收以及超时、空闲检测等策略。 实现Socket连接池的步骤大致如下: ...

    java 数据库 连接池驱动.rar

    Java数据库连接池驱动是Java开发中不可或缺的一部分,通过有效管理数据库连接,提高了系统的运行效率和稳定性。理解并熟练运用不同的连接池库,对于优化数据库访问性能至关重要。在实际应用中,应结合具体需求选择...

    连接池案例 连接池案例

    在实际应用中,开发者通常会在Spring框架中配置数据源,选择合适的连接池实现,如在Spring Boot项目中,可以通过YAML或properties配置文件设置连接池的相关参数: ```yaml spring: datasource: type: ...

    JAVA+ACCESS连接池(精典)

    在Java编程中,数据库...通过以上知识,你可以理解如何在Java应用程序中利用连接池与ACCESS数据库交互,提高系统的性能和可伸缩性。在实际项目中,根据具体需求选择合适的数据库和连接池实现,以达到最佳的性能效果。

    java手写数据库连接池

    本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及如何通过多线程进行数据库操作的测试。 首先,数据库连接池的基本原理是维护一定数量的数据库连接,当...

    Java 连接池实现

    4. **连接池实现**:在Java中,可以使用`java.util.concurrent`包中的数据结构(如`BlockingQueue`)来实现连接池。当应用程序请求连接时,池会检查是否有空闲连接;如果没有,就等待直到有连接被归还。归还连接时,...

    java apache 数据库连接池 天涯浪子

    在Java Web开发中,数据库连接池是不可或缺的一部分,尤其是在高并发环境下。 天涯浪子可能是在指一个开发者或教程作者,他分享了关于如何在Java项目中使用Apache数据库连接池的具体方法和实践经验。以下是对这个...

    JDBC数据源连接池的配置和使用示例

    了解和掌握数据源连接池的配置和使用是每个Java开发者必备的技能。通过选择合适的连接池,配置合理的参数,以及有效利用监控工具,可以大大提高应用的性能和稳定性。在实际项目中,应根据具体需求选择合适的数据源,...

    Java 连接池源码

    在Java连接池的上下文中,JNDI常被用来查找和获取数据源,即连接池的实例。通过JNDI,应用可以在运行时动态查找和绑定数据源,使配置更加灵活和方便。 总的来说,理解和实现Java连接池源码是一项有价值的实践,它能...

    JAVA数据库连接池

    总的来说,数据库连接池是Java开发中不可或缺的一部分,它通过有效地管理和复用数据库连接,提高了系统的运行效率和资源利用率。了解和掌握C3P0和DBCP的使用方法,能够帮助开发者更好地优化数据库操作,提升应用性能...

    java红数据连接池包下载

    标题提到的"java红数据连接池包下载",指的是包含了Proxool连接池及其依赖的Java包。 首先,我们要理解数据库连接池的基本概念。数据库连接池在应用程序启动时创建一定数量的数据库连接,并将它们存储在内存中,以...

    Java各数据库连接池配置介绍

    Java数据库连接池是管理数据库连接的一种机制,它可以有效地复用数据库连接,避免每次数据库操作时创建和销毁连接的开销,从而提高了应用的性能。在Java中,有多种数据库连接池实现,包括C3P0、DBCP和Proxool等。 *...

Global site tag (gtag.js) - Google Analytics