自己写了个连接池

自己写了个连接池,不过性能不理想,当模拟1000个线程去连接数据库时,会在getConnection这个方法里爆出空指针。

 

oracle的配置文件:

 

driver = oracle.jdbc.driver.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:DB
user = username
password = pwd
defaultRowPrefetch=50
defaultExecuteBatch=25
poolsize=20
islation=2

 

连接池:

package com.connection;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;

import java.util.Map;
import java.util.Properties;

import com.util.PropertiesHelper;

import oracle.jdbc.driver.OracleConnection;

public class ConnectionPool {
	private static Map<Connection, Boolean> pool = new HashMap<Connection, Boolean>();
	
	public static DataBase db=null;
	
	private static Properties prop;

	private static int POOLSIZE = 5;


	public static synchronized void init(String file){
		if (pool.size() == 0) {
			try {
				
				prop = readProperties(file);
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				Class.forName(prop.getProperty("driver"));
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
			if (prop.getProperty("poolsize").length() > 0)
				POOLSIZE = Integer.parseInt(prop.getProperty("poolsize"));

			for (int i = 0; i < POOLSIZE; i++) {
				pool.put(newConnection(), true);
			}
		}
	}

	private static synchronized Connection newConnection() {
		Connection conn=null;
		try {
			String url=prop.getProperty("url");
			conn = DriverManager.getConnection(url, prop);
			conn.setTransactionIsolation(Integer.parseInt(prop.getProperty("islation")));
			conn.setAutoCommit(false);
			} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	

	
	public static void closeAll() {
		for (Connection c : pool.keySet()) {
			try {
				c.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static Connection getConnection() {
		synchronized (pool) {
			for (Connection conn : pool.keySet()) {
				if (pool.get(conn) == false) {
					pool.put(conn, true);
					return conn;
				}
			}
		}
		Connection c=newConnection();
		return c;
	}

	public static void release(Connection conn) {
		if (conn != null) {
			synchronized (pool) {
				if (!pool.keySet().contains(conn)) {
					try {
						conn.close();
					} catch (SQLException e) {
						throw new RuntimeException(e);
					}
				} else
					pool.put(conn, false);
			}
		}
	}

	public static void closePool() {
		for (Connection conn  : pool.keySet()) {
			try {
				conn.close();
				pool.clear();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	private static Properties readProperties(String file) throws IOException {
		Properties result = new Properties();
		InputStream is = ConnectionPool.class.getClassLoader()
				.getResourceAsStream(file);
		result.load(is);
		return result;
	}
}

 

测试代码:

 

package com.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.connection.ConnectionPool;
import com.dao.BaseDAO;

public class Test extends Thread{
	
	 private String sql;  
	      
	     private Connection c;  
	     public Test(Connection c,String sql){  
	         
	         this.c=c;  
	         this.sql=sql;  
	     }  
	
	  public static void main(String[] args) {  
		  ConnectionPool.init("oracle.properties"); 
		 
		         for(int i=0;i<100;i++){  
		             String sql="select sysdate from dual";  
		             new Test(ConnectionPool.getConnection(),sql).start();  
		         }  
		   
		     }  
		       
		     public void run(){  
		         try {  
		             System.out.println(c);
		        	 ResultSet rs=c.createStatement().executeQuery(sql);  
		             while(rs.next()){  
		                 System.out.println(rs.getString(1));  
		             }  
		             
		         } catch (SQLException e) {  
		             e.printStackTrace();  
		         }finally{  
		        	 ConnectionPool.release(c);  
		         }  
		     }  
}

 

 

模拟100个线程完全没问题,但是数量一旦上去了就不行了  连接池得不到连接了。

 

我的思路是当你请求一个资源,池会看看池中有没有资源,有的话把这个资源分发给请求,没有的话,生成新的资源同时把该资源放到池中。当请求归还的时候,池会判断池中是否满了,如果满了,那么释放该资源。其中关键的,就是生成新资源,判断是否释放资源。

 

我自己写是为了多学点知识  一直用别人封装好的连接池  没什么意思,个人写的很烂,欢迎有技术性的建议。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值