Mysql連接池解決併發問題

/**
 * 連接池類
 */
packagecom.junones.test;
 
importjava.sql.Connection;
importjava.sql.SQLException;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.Map.Entry;
 
importcom.mysql.jdbc.jdbc2.optional.MysqlDataSource;
 
publicclass MySQLPool {
    privatestatic volatile MySQLPool pool;
    privateMysqlDataSource ds;
    privateMap<Connection, Boolean> map;
  
    privateString url = "jdbc:mysql://localhost:3306/test";
    privateString username = "root";
    privateString password = "root1234";
    privateint initPoolSize = 10;
    privateint maxPoolSize = 200;
    privateint waitTime = 100;
     
    privateMySQLPool() {
        init();
    }
     
    publicstatic MySQLPool getInstance() {
        if(pool == null) {
            synchronized(MySQLPool.class) {
                if(pool == null) {
                    pool = newMySQLPool();
                }
            }
        }
        returnpool;
    }
     
    privatevoid init() {
        try{
            ds = newMysqlDataSource();
            ds.setUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            ds.setCacheCallableStmts(true);
            ds.setConnectTimeout(1000);
            ds.setLoginTimeout(2000);
            ds.setUseUnicode(true);
            ds.setEncoding("UTF-8");
            ds.setZeroDateTimeBehavior("convertToNull");
            ds.setMaxReconnects(5);
            ds.setAutoReconnect(true);
            map = newHashMap<Connection, Boolean>();
            for(inti = 0; i < initPoolSize; i++) {
                map.put(getNewConnection(),true);
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
     
    publicConnection getNewConnection() {
        try{
            returnds.getConnection();
        }catch(SQLException e) {
            e.printStackTrace();
        }
        returnnull;
    }
     
    publicsynchronized Connection getConnection() {
        Connection conn = null;
        try{
            for(Entry<Connection, Boolean> entry : map.entrySet()) {
                if(entry.getValue()) {
                    conn = entry.getKey();
                    map.put(conn,false);
                    break;
                }
            }
            if(conn == null) {
                if(map.size() < maxPoolSize) {
                    conn = getNewConnection();
                    map.put(conn,false);
                }else{
                    wait(waitTime);
                    conn = getConnection();
                }
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        returnconn;
    }
     
    publicvoid releaseConnection(Connection conn) {
        if(conn == null) {
            return;
        }
        try{
            if(map.containsKey(conn)) {
                if(conn.isClosed()) {
                    map.remove(conn);
                }else{
                    if(!conn.getAutoCommit()) {
                        conn.setAutoCommit(true);
                    }
                    map.put(conn,true);
                }
            }else{
                conn.close();
            }
        }catch(SQLException e) {
            e.printStackTrace();
        }
    }
}
 
/**
 * 測試類
 */
packagecom.junones.test;
 
importjava.sql.Connection;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importjava.sql.Statement;
 
publicclass TestMySQLPool {
    privatestatic volatile int a;
 
    privatesynchronized static void incr() {
        a++;
    }
 
    publicstatic void main(String[] args) throwsInterruptedException {
        inttimes = 10000;
        longstart = System.currentTimeMillis();
        for(inti = 0; i < times; i++) {
            newThread(newRunnable() {
 
                @Override
                publicvoid run() {
 
                    MySQLPool pool = MySQLPool.getInstance();
                    Connection conn = pool.getConnection();
                    Statement stmt = null;
                    ResultSet rs = null;
                    try{
                        stmt = conn.createStatement();
                        rs = stmt.executeQuery("select id, name from t_test");
                        while(rs.next()) {
                            System.out.println(rs.getInt(1) + ", "
                                    + rs.getString(2));
                        }
                    }catch(SQLException e) {
                        e.printStackTrace();
                    }finally{
                        incr();
                        if(rs != null) {
                            try{
                                rs.close();
                            }catch(SQLException e) {
                                e.printStackTrace();
                            }
                        }
                        if(stmt != null) {
                            try{
                                stmt.close();
                            }catch(SQLException e) {
                            }
                        }
                        pool.releaseConnection(conn);
                    }
                }
            }).start();
        }
        while(true) {
            if(a == times) {
                System.out.println("finished, time:"
                        + (System.currentTimeMillis() - start));
                break;
            }
            Thread.sleep(100);
        }
    }
}
 
測試結果:1萬個併發,5秒完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章