`
yunchow
  • 浏览: 319795 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

数据源简单实现

    博客分类:
  • DBI
阅读更多
package com.yunchow.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

/**
 * 自定义数据源
 * @author yunchow
 * @version 1.2  09/8/6
 */
public class MyDataSource {

	private static final String DRIVER_CLASS_NAME;
	private static final String URL;
	private static final String USER;
	private static final String PASSWORD;
	private static final int INIT_CONNECTION;
	private static final int MAX_CONNECTION;
	private static final int MAX_IDLE_CONNECTION;
	/** 当前连接数 **/
	private static int currentConnection = 0;
	/** 连接缓冲池 */
	private static final LinkedList<Connection> pool; 
	/** 正在等待连接的线程个数 **/
	private static int waitCount = 0;
	
	static {
		DRIVER_CLASS_NAME = JdbcConfigBean.getInstance().getProperty("driver");
		URL = get("url");
		USER = get("user");
		PASSWORD = get("password");
		String init = get("initConnection");
		if(init != null)
			INIT_CONNECTION = Integer.parseInt(init);
		else
			INIT_CONNECTION = 5;
		String max = get("maxConnection");
		if(max != null)
			MAX_CONNECTION = Integer.parseInt(max);
		else
			MAX_CONNECTION = 10;
		String idle = get("idleConnection");
		if(idle != null)
			MAX_IDLE_CONNECTION = Integer.parseInt(idle);
		else
			MAX_IDLE_CONNECTION = INIT_CONNECTION;
		pool = new LinkedList<Connection>();
		try {
			// 加载驱动
			Class.forName(DRIVER_CLASS_NAME);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public MyDataSource() {
		for(int i=0; i<INIT_CONNECTION; i++) {
			currentConnection ++;
			pool.addLast(createConnectionProxy());
		}
		new PoolScan().start(); // 启动后台线程,扫描连接池
	}
	
	/**
	 * 扫描当前池里的空闲线程,并将其释放
	 */
	private class PoolScan extends Thread {
		public void run() {
			try {
				while(true) {
					//System.out.print("当前连接数: " + pool.size());
					//System.out.println("\t最多空闲数: " + MAX_IDLE_CONNECTION);
					Thread.sleep(3000); // 每一秒扫描一次连接池
					if(pool.size() > MAX_IDLE_CONNECTION) {
						//System.out.println("发现多于的空闲连接");
						for(int i=0; i<pool.size()-MAX_IDLE_CONNECTION; i++) {
							((DBSourceRelease)pool.removeFirst()).release(); // 释放连接
							currentConnection --; // 将当前可用连接数减一
							System.out.println("Thread-daemo : release();");
						}
					}
				}
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}
	}
	
	private static Connection createConnectionProxy() {
		Connection proxy = null;
		// System.out.println("createConnectionProxy");
		try {
			Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
			// System.out.println("xxxxxxxx"+conn);
			proxy = new MyConnection(conn).getProxy(); 
		} catch(Exception ex) {
				throw new ExceptionInInitializerError(ex);
		}
		return proxy;
	}
	
	private static String get(String arg) {
		return JdbcConfigBean.getInstance().getProperty(arg);
	}
	/**
	 * 从缓冲池中获取一个连接,如果连接还没有达到最大的连接数,便等待
	 * 如果还等不到,就抛出数据库异常
	 */
	public Connection getConnection() throws SQLException {
		if(pool.size() > 0) {
			synchronized(pool) {
				if(pool.size()>0)
					return pool.removeFirst();
			}
		} else if(currentConnection < MAX_CONNECTION) {
			currentConnection ++;
			return createConnectionProxy();
		} else if(currentConnection == MAX_CONNECTION) {
			synchronized(pool) {
				try {
					waitCount ++;
					//System.out.println("wait .... ");
					pool.wait();
					if(pool.size()>0)
						return pool.removeFirst();
				} catch(Exception ex) {
					throw new SQLException("MyDataSource : timeout ");
				}
			}
			throw new SQLException("MyDataSource : timeout ");
		}
		
		throw new SQLException("MyDataSource : no more connection ");
    }
	/**
	 * 归还连接, 同时还要唤醒正在等待中的线程
	 *
	 */
	public static void rebackConnection(Connection conn) {
		synchronized(pool) {
			pool.addLast(conn);
			if(waitCount > 0) {
				pool.notifyAll();
				//System.out.println("notifyAll .... ");
			}
		}
	}
								 
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics