临界资源需要保持他的唯一性,再代码中,可以通过单例模式来实现(这里是典型的生产者/消费者问题)
构造方法中,用synchronized来做同步处理,为了避免每次进来都要给代码加锁影响性能,先在外层套if做判断
这里的connectionMap就是一个临界资源,代码初始化创建了8个数据库链接,放在map里面,然后多线程来获取调用这些connection
为了保证临界资源的安全,对获取链接和放回链接做了一个枷锁的处理,建立一个ReentrantLock锁,然后获取两个条件,获取连接的时候,判断是否有链接,有就继续,放回链接的时候,判断链接池是否已经满了,没满就放回
package cn.com.enersun.datahub.powerevent.consumer.database;
import java.sql.Connection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Postgres执行器
* @author Mr.Wen
*/
public class Postgresql extends DatabaseCommonOperator implements Database{
private static final int CONNECTION_POOL_SIZE = 8;
private static Map<String,LinkedList<Connection>> connectionMap = new HashMap<>();
private static volatile Postgresql postgresql = null;
private Lock lock;
private Condition consumer;
private Condition producer;
private Postgresql(){
lock = new ReentrantLock();
consumer = lock.newCondition();
producer = lock.newCondition();
}
/**
* 初始化对象,创建链接池
* @param driveClassName 数据库驱动名称
* @param url 数据库连接
* @param username 数据库用户名
* @param password 数据库密码
* @return 返回对象
*/
public static Postgresql getInstance(String driveClassName,String url, String username, String password){
//第一次加载
if(null == postgresql){
synchronized (Postgresql.class){
if(null == postgresql){
postgresql = new Postgresql();
LinkedList<Connection> connectionsList = new LinkedList<>();
for(int i=0;i<CONNECTION_POOL_SIZE;i++){
connectionsList.add(createConnection(driveClassName,url,username,password));
}
connectionMap.put(url,connectionsList);
}
}
}else{
synchronized (Postgresql.class){
if(!connectionMap.containsKey(url)){
LinkedList<Connection> connectionsList = new LinkedList<>();
for(int i=0;i<CONNECTION_POOL_SIZE;i++){
connectionsList.add(createConnection(driveClassName,url,username,password));
}
connectionMap.put(url,connectionsList);
}
}
}
return postgresql;
}
public Connection getConnection(String url) {
lock.lock();
try{
LinkedList<Connection> connections = connectionMap.get(url);
while (connections.size() == 0){
consumer.wait();
}
Connection connection = connections.remove(0);
producer.signal();
return connection;
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
return null;
}
public void returnConnection(Connection connection,String url){
lock.lock();
try {
LinkedList<Connection> connections = connectionMap.get(url);
while (connections.size() == CONNECTION_POOL_SIZE){
producer.wait();
}
consumer.signal();
connections.add(connection);
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}