当前位置:首页 > 芯闻号 > 充电吧
[导读]import java.sql.*;import java.util.*;import java.io.*;/** *  * Title:数据库连接池 *  *  * Description:本连接池

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

/**
 *


 * Title:数据库连接池
 *


 *


 * Description:本连接池支持对失效连接重连、重建连接池,并监控调用者及调用时间
 * 本类需要在类路径根中存在db.properties数据库配置文件,文件内容示例:
 * drivers=net.sourceforge.jtds.jdbc.Driver
 * defaultpoolname.url=jdbc:jtds:sqlserver://192.167.1.107:1433/wapplat;charset=gb2312
 * defaultpoolname.user=sa
 * defaultpoolname.password=lutong
 * defaultpoolname.maxconn=20
 *


 *


 * Copyright: Copyright (c) 2005
 *


 *


 * Company:lutong
 *


 *
 * @author DBoy
 * @version 1.0
 */

public class ConnectPool extends Thread
{  
    /* 连接池,存放已创建但未使用的连接 */
    private Stack pool = new Stack();

    /* 被返回的数据库连接,将由线程检测并返回到池中 */
    private Stack returnedPool = new Stack();

    /* 已被取走、正在使用的连接 */
    private Map using = new HashMap();

    /* 已经创建连接池计数 */
    private int created = 0;

    /* JDBC Driver类 */
    String drivers = null;

    /* 数据库连接字符串 */
    String url = null;

    /* 数据库连接用户名 */
    String user = null;

    /* 数据库连接密码 */
    String password = null;

    /* 连接池最大数 */
    int max = 100;

    /* 连接池最小数 (还未实现)*/
    int min = 10;

    /* 空闲连接等待释放的时间(秒) ,(还未实现)*/
    int idleTime = 1800;
   
    /*是否需要停止线程*/
    boolean stopThread = false;

    /*各种同步锁对象,据说byte[]对象创建时间最短,占资料最少*/
    private byte[] createdLock = new byte[0];
    private byte[] usingLock = new byte[0];
    private byte[] poolLock = new byte[0];
    private byte[] returnedPoolLock = new byte[0];
   
    /*单实例*/
    private static ConnectPool instance = new ConnectPool();

    /**
     * 私有的构造方法,防止从外部直接实例化
     * 
     */
    private ConnectPool()
    {
        /* 初始化数据库连接参数 */
        init();

        /* 启动服务线程 */
        start();
    }

    /**
     * 从外部取得本类实例的唯一方法
     *
     * @return ConnectPool
     */
    public static ConnectPool getInstance()
    {
        return instance;
    }

    /**
     * 从连接池中取得一个数据库连接
     * 如果池中已没有连接,则新创建一个连接
     * 被使用的连接放到using对象里
     * @param caller
     * @return
     */
    public Connection getConnection(String poolname, String caller)
    {
        if(null==caller || caller.length()==0)
        {           
            StackTraceElement[] callerStackTrace = new Throwable().getStackTrace();
            caller = callerStackTrace[1].toString();
        }
        Connection conn = null;
        try
        {
            synchronized(poolLock)
            {
                conn = (Connection) pool.pop();  
            }
        }
        catch (EmptyStackException e)
        {
            conn = newConnection();
        }

        if (null != conn)
        {
            synchronized(usingLock)
            {
                using.put(conn, new UsingConnection(conn, caller));
            }
        }
        return conn;
    }

    /**
     * 创建一个新的数据库连接
     *
     * @return
     */
    private Connection newConnection()
    {
        Connection conn = null;
        try
        {
            if (created < max)
            {
                Class.forName(drivers);
                conn = DriverManager.getConnection(url, user, password);
                if (null != conn)
                {
                    synchronized(createdLock)
                    {
                        created++;
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 返回一个数据库连接到池中,再由线程返回连接池
     *
     * @param conn
     */
    public void freeConnection(Connection conn)
    {
        freeConnection(null, conn);
    }

    public void freeConnection(String poolName, Connection conn)
    {
        if (null != conn)
        {
            synchronized(returnedPoolLock)
            {
                returnedPool.push(conn);
            }
        }
    }

    /**
     * 初始化数据库连接使用的参数
     * 
     */
    private void init()
    {
        InputStream is = getClass().getResourceAsStream("/db.properties");
        Properties dbProps = new Properties();
        try
        {
            dbProps.load(is);
        }
        catch (Exception e)
        {
            System.err.println("Can't read the properties file. " + "Make sure db.properties is in the CLASSPATH");
            return;
        }
        drivers = dbProps.getProperty("drivers");
        url = dbProps.getProperty("defaultpoolname.url");
        user = dbProps.getProperty("defaultpoolname.user");
        password = dbProps.getProperty("defaultpoolname.password");
        max = Integer.parseInt(dbProps.getProperty("defaultpoolname.maxconn"));       
    }

    /**
     * 连接服务线程,主要作用: 记录已取走的连接 测试返回的连接是否可用
     */
    public void run()
    {
        Connection conn = null;
        UsingConnection uc = null;
        while (true  && !stopThread)
        {
            /*
             * 处理被返回的数据库连接 判断连接是否由本池创建并发出的,如果不是则直接关闭
             * 如果是则测试连接是否有效,无效从池中删除,有效则返回池中
             */
            while (!returnedPool.empty())
            {
                synchronized(returnedPoolLock)
                {
                    conn = (Connection) returnedPool.pop();
                }
                synchronized(usingLock)
                {
                    uc = (UsingConnection) using.get(conn);
                }
                if (null == uc)
                {
                    try
                    {
                        conn.close();
                    }
                    catch (Exception e)
                    {
                    }
                }
                synchronized(usingLock)
                {
                    using.remove(conn);
                }

                if (testOK(conn))
                {
                    synchronized(poolLock)
                    {
                        pool.add(conn);
                    }
                }
                else
                {
                    try
                    {
                        conn.close();
                    }
                    catch (Exception e)
                    {
                    }
                    synchronized(createdLock)
                    {
                        created--;
                    }
                }
            }

            conn = null;
            uc = null;
            /* 避免循环太快 */
            try
            {
                Thread.sleep(50);
            }
            catch (InterruptedException ie)
            {
            }
        }
        stopThread = false;
    }

    /**
     * 测试连接是否正常
     *
     * @param conn
     * @return
     */
    public boolean testOK(Connection conn)
    {
        boolean result = false;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try
        {
            pstmt = conn.prepareStatement("select 1");
            rs = pstmt.executeQuery();
            result = true;
        }
        catch (Exception e)
        {
        }
        finally
        {
            if (null != rs)
            {
                try
                {
                    rs.close();
                }
                catch (Exception e)
                {
                }
            }
            if (null != pstmt)
            {
                try
                {
                    pstmt.close();
                }
                catch (Exception e)
                {
                }
            }
        }
        return result;
    }

    /**
     * 取得当前正使用的连接信息(HTML格式)
     *
     * @return
     */
    public String getUsingHTMLInfo()
    {

        StringBuffer info = new StringBuffer();
        info.append("Driver:" + drivers + "
");
        info.append("Connect url:" + url + "
");
        synchronized(createdLock)
        {
            info.append("Created connection count:" + created + "
");
        }
        synchronized(usingLock)
        {
         info.append("Using connection count:" + using.values().size() + "

");
         info.append("

");
         Iterator it = using.values().iterator();
        
         UsingConnection uc = null;
         while (it.hasNext())
         {
             uc = (UsingConnection) it.next();
             info.append("");
         }
        }
        info.append("
CallerUsing Time(ms)
");
             info.append(uc.getCaller());
             info.append("
");
             info.append(uc.getUsingTime());
             info.append("
");
        return info.toString();
    }

    /**
     * 释放所有连接,创建新池
     */
    public void release()
    {  
        /*要求停止线程*/
        stopThread = true;
       
        /*停等待线程结束,线程结束时会把stopThread置为false*/
        int timeout = 0;
        while(stopThread)
        {  
            if(++timeout>600)
            {
                break;
            }
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException ie)
            {
            }
        }
       
        /*创建新连接池实例*/
        instance = new ConnectPool();
       
        /*释放所有连接,除了Using,Using是正在使用的且会在新的池里被释放*/
        synchronized(poolLock)
        {
         while(!pool.isEmpty())
         {  
             try
             {
                 Connection conn = (Connection)pool.pop();
                 conn.close();
             }
             catch(Exception e)
             {               
             }
         }
        }
    
        synchronized(returnedPoolLock)
        {
         while(!returnedPool.isEmpty())
         {  
             try
             {
                 Connection conn = (Connection)returnedPool.pop();
                 conn.close();
             }
             catch(Exception e)
             {               
             }
         }
        }
    }
}

/**
 * 用户存储当前被使用的数据库连接信息
 */
class UsingConnection
{
    private Connection conn = null;

    private String caller = null;

    long time = 0;

    public UsingConnection(Connection conn, String caller)
    {
        this.conn = conn;
        this.caller = caller;
        time = System.currentTimeMillis();
    }

    public String getCaller()
    {
        return caller;
    }

    public long getUsingTime()
    {
        return System.currentTimeMillis() - time;
    }
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭