⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poolmanager.java

📁 信息发布 发布系统 动态的菜单 和 信息统计
💻 JAVA
字号:
/**
 * 
 */
package com.xuntian.material.data.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Hashtable;

import com.xuntian.material.data.idao.ConnectPool;
import com.xuntian.material.exception.ConnectPoolException;
import com.xuntian.material.util.Constants;
import com.xuntian.material.util.DBConfig;
import com.xuntian.material.util.LogUtil;

/**
 * @author zym
 */
public class PoolManager implements ConnectPool {
    /**
     * driver name
     */
    private String driver = null;

    /**
     * db username
     */
    private String userName = null;

    /**
     * db password
     */
    private String password = null;

    /**
     * the driver URL
     */
    private String url = null;

    /**
     * test table name
     */
    private String testTable = null;
    /**
     * 最大连接数
     */
    private int maxSize = 0;

    /**
     * 最小连接数
     */
    private int minSize = 0;

    /**
     * 所有unlock连接失效时间,失效后重新建立
     */
    private long expirationTime = 0L;

    /**
     * 初始化连接个数
     */
    private int initSize = 0;

    /**
     * singleton建立poolManager
     */
    private static PoolManager poolManager = new PoolManager();

    /*
     * 链接存放容器
     */
    private Hashtable<Connection, Long> locked = null;

    private Hashtable<Connection, Long> unlocked = null;

    /**
     * 
     */
    private PoolManager() {
        driver = DBConfig.DRIVER;
        url = DBConfig.URL;
        maxSize = DBConfig.MAX_SIZE;
        minSize = DBConfig.MIN_SIZE;
        expirationTime = DBConfig.EXPIRATION_TIME;
        initSize = DBConfig.INIT_SIZE;
        userName = DBConfig.USERNAME;
        password = DBConfig.PASSWORD;
        testTable = DBConfig.TEST_TABLE;

    	//System.out.println(driver+url+userName+password);
        init();
    }

    /**
     * @return PoolManager
     */
    public static PoolManager getInstance() {
        return poolManager;
    }

    /**
     * 初始化数据库连接, 同时启动对未使用连接的监控, 如果超时则使其失效
     */
    private synchronized void init() {
        try {
            if (initSize <= 0) {
                throw new ConnectPoolException("the initSize is wrong: "
                        + initSize);
            }
            unlocked = new Hashtable<Connection, Long>(initSize);
            locked = new Hashtable<Connection, Long>(initSize);
            for (int i = 0; i < initSize; i++) {
                Connection conn = create();
                LogUtil.getLogger(this).info(conn);
                unlocked.put(conn, new Long(System.currentTimeMillis()));
            }
            new AdjustPoolTools().start();
        } catch (ConnectPoolException e) {
            e.printStackTrace();
        }
        notifyAll();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#checkIn(java.sql.Connection)
     */
    public synchronized void checkIn(Connection con)
            throws ConnectPoolException {
        if (con != null) {
            unlocked.put(con, locked.get(con));
            locked.remove(con);
        } else {
            LogUtil.getLogger(this).error("null checkIn connection");
            throw new ConnectPoolException("the checkIn connection is null!");
        }
        notifyAll();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#checkOut()
     */
    public synchronized Connection checkOut() throws ConnectPoolException {
        Long now = System.currentTimeMillis();
        Connection conn = null;
        synchronized(unlocked){
        if (unlocked.size() > 0) {
            int getTimes=0;
            for (Enumeration<Connection> enu = unlocked.keys();enu.hasMoreElements();){
                int random=(int)(Math.random()*minSize);
                if(random!=0){
                    random--;
                    getTimes+=1;
                    if(getTimes<=(minSize/2)){
                        conn = enu.nextElement();
                        continue;
                    }
                }
                conn = enu.nextElement();
                if (validate(conn)) {
                    locked.put(conn, unlocked.get(conn));
                    unlocked.remove(conn);
                    long cnow = System.currentTimeMillis();
                    if (cnow - now > Constants.DB_KEY_TIMEOUT) {
                        notifyAll();
                        throw new ConnectPoolException(
                                "get connection form the unlocked time out!");
                    }
                    notifyAll();
                    return conn;
                } else {
                    this.expire(conn);
                    unlocked.remove(conn);
                    boolean isOk = false;
                    while (!isOk) {
                        conn = create();
                        isOk = validate(conn);
                        if (isOk) {
                            locked.put(conn, new Long(System
                                    .currentTimeMillis()));
                            notifyAll();
                            return conn;
                        }
                        
                    }
                }
            }
        } else if (unlocked.size() == 0 && locked.size() < maxSize) {
            boolean createOk = false;
            while (!createOk) {
                conn = this.create();
                if (validate(conn)) {
                    createOk = true;
                    locked.put(conn, new Long(System.currentTimeMillis()));
                    if (locked.get(conn).longValue() - now > Constants.DB_KEY_TIMEOUT) {
                        notifyAll();
                        throw new ConnectPoolException(
                                "create connection time out!");
                    }
                    notifyAll();
                    return conn;
                }
            }
        }
        }
        notifyAll();
        return conn;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#monitorPool()
     */
    public void monitorPool() {
        String message = "the used connection amount is :" + locked.size()
                + "the NOT used connection amount is" + unlocked.size();
        LogUtil.getLogger(PoolManager.class).info(message);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#create()
     */
    public Connection create() throws ConnectPoolException {
        Connection conn = null;
        if (unlocked.size() == 0 || (unlocked.size() + locked.size()) < maxSize) {
            try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, userName, password);
            } catch (ClassNotFoundException e) {
                String errorMessage = "Database driver can not find!";
                LogUtil.getLogger(this).error(errorMessage);
                throw new ConnectPoolException(errorMessage, e);
            } catch (SQLException e) {
                String errorMessage = "The config of database connection is wrong!";
                LogUtil.getLogger(this).error(errorMessage);
                throw new ConnectPoolException(errorMessage, e);
            }

        }
        
        return conn;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#validate(java.sql.Connection)
     */
    public boolean validate(Connection con) throws ConnectPoolException {
        boolean isOk = false;
        if(con!=null){
            try {
                String sql = "select 1 from "+testTable;
                Statement st = con.createStatement();
                isOk = st.execute(sql);
            } catch (SQLException e) {
                LogUtil.getLogger(this).error("the connection now using is bad");
            }
        }
        return isOk;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.xuntian.data.dao.ConnectPool#expire(java.sql.Connection)
     */
    public void expire(Connection con) throws ConnectPoolException {
        try {
            con.close();
        } catch (SQLException e) {
            LogUtil.getLogger(this).error("Close connection error!");
            throw new ConnectPoolException("Close connection error!", e);
        }

    }
    public synchronized void clearConn(Connection con) throws ConnectPoolException{
        expire(con);
        unlocked.remove(con);
        notifyAll();
    }

    /**
     * @author lip Mar 7, 2006 copyright@xuntian 启动监视线程
     */
    class AdjustPoolTools extends Thread {
        public void run() {
            try {
                while (true) {
                    sleep(expirationTime);
//                    sleep(60000L);
                    monitorPool();
                    Hashtable<Connection, Long> newConn = new Hashtable<Connection, Long>(
                            );
                    for (int i = 0; i < minSize; i++) {
                        Connection con = create();
                        if (!validate(con)) {
                            i--;
                            continue;
                        }
                        newConn.put(con, new Long(System.currentTimeMillis()));
                    }
                    
                        Enumeration<Connection> enu = unlocked.keys();
                        while (enu.hasMoreElements()) {
                            Connection conn = enu.nextElement();
                            if (checkTime(unlocked.get(conn).longValue())) {
                                clearConn(conn);
                                LogUtil.getLogger(this).info("连接被关掉!");
                            } 
                        }
                        unlocked.putAll(newConn);
                        monitorPool();
                    // sort(unlocked);
                    }
            
                
            
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ConnectPoolException e) {
                e.printStackTrace();
            }
        }
        

        /**
         * @param createTime
         * @return true:time out false:NOT timeout
         */
        private boolean checkTime(long createTime) {
            long now = System.currentTimeMillis();
            if (now - createTime > expirationTime) {
                return true;
            }
            return false;
        }
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -