// 1. 使用LinkedList,並由調用者傳入參數初始化大小;
// 2. LinkedList從尾部添加,從頭部拿
// 3. 使用完歸還到池子
// 4. 連接超時返回空
// 5. 使用synchronized
package com.zzf.concurrence.dbpool;
import java.sql.Connection;
import java.util.LinkedList;
public class DbPool {
private final LinkedList<Connection> pool =new 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();
}
}
}