package com.zzf.concurrence.dbpool;
import java.sql.Connection;
import java.util.LinkedList;
public class DbPool {
private final LinkedList
// 1. 使用LinkedList,并由调用者传入参数初始化大小;
// 2. LinkedList从尾部添加,从头部拿
// 3. 使用完归还到池子
// 4. 连接超时返回空
// 5. 使用synchronized
public void initPool(int size) {
if(size>0) {
for (int i = 0; i < size; i++) {
pool.addLast(new ConnectionImp());
}
}
}
/**
*
* @param timeout 小于0永不超时
* @return
* @throws InterruptedException
*/
public Connection getConnection(long timeout) throws InterruptedException {
Connection result =null;
synchronized (pool) {
if(timeout>=0) { //超时的情况
long remindTime =timeout;
long willtimeout =System.currentTimeMillis()+timeout;
while(pool.isEmpty() && remindTime>0) { //空或未超时
pool.wait(remindTime); //等待其它线程释放锁
remindTime =willtimeout -System.currentTimeMillis(); //能执行到这里,说明有其它线程释放了锁
}
if(!pool.isEmpty()) {
result = pool.removeFirst();
if(result !=null)return result;
//如果为空,继续while
}
}else { //永不超时
if(pool.isEmpty()) {
pool.wait();
}
if(!pool.isEmpty())
result = pool.removeFirst();
}
}
return result;
}
public void releaseConnection(Connection conn) {
if(conn!=null) {
synchronized (pool) {
pool.addLast(conn);
pool.notifyAll();
}
}
}
}
测试类:
package com.zzf.concurrence.dbpool;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class DbPoolTest {
//初始化一个一个静态连接池 ,开50个线程去,超时重试10次,打印成功获取连接池,成功与失
private static DbPool pool =new DbPool();
private static final int threadCount =50;
private static int count =20;
private static CountDownLatch cd;
public static void main(String[] args) throws InterruptedException {
pool.initPool(10);
AtomicInteger getCount =new AtomicInteger(0);
AtomicInteger noGet = new AtomicInteger(0);
cd =new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(new WorkThread(getCount, noGet,count),"workThread-"+i).start();
}
cd.await();
System.out.println("总共尝试了: " + (threadCount * count));
System.out.println("50个线程中获取成功的次数:"+getCount);
System.out.println("50个线程中获取失败的次数:"+noGet);
}
public static class WorkThread implements Runnable{
private AtomicInteger getCount ;
private AtomicInteger noGet ;
private int count;
public WorkThread(AtomicInteger getCount, AtomicInteger noGet,int count) {
super();
this.getCount = getCount;
this.noGet = noGet;
this.count = count;
}
@Override
public void run() {
while(count>0) {
Connection connection =null;
try {
try {
connection = pool.getConnection(1000);
if(connection!=null) {
connection.createStatement();
connection.commit();//休眠50ms
getCount.incrementAndGet();
// System.out.println(Thread.currentThread().getName()+"-->尝试连接成功");
}else {
noGet.incrementAndGet();
System.out.println(Thread.currentThread().getName()+"-->尝试连接,但超时");
}
} catch (Exception e) {
e.printStackTrace();
}
} finally {
if(connection!=null) {
pool.releaseConnection(connection);
connection =null;
}
}
count--;
}
cd.countDown();
}
}
}