模拟一个ConnectionDriver,用于创建Connection

package tread.demo.threadpool;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.concurrent.TimeUnit; public class ConnectionDriver {
static class ConnectionHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
} public static final Connection createConnection() {
return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class}, new ConnectionHandler());
}
}

线程池的实现:

package tread.demo.threadpool;

import java.sql.Connection;
import java.util.LinkedList; public class ConnectionPool {
private LinkedList<Connection> pool = new LinkedList<Connection>(); public ConnectionPool(int initialSize) {
if (initialSize > 0) {
for (int i = 0; i < initialSize; i++) {
pool.addLast(ConnectionDriver.createConnection());
}
}
} public void releaseConnection(Connection connection) {
if (connection != null) {
synchronized (pool) {
pool.addLast(connection);//将Connection还回给Pool
pool.notifyAll();//通知等待的线程
}
}
} public Connection fetchConnection(long mills) throws Exception {
synchronized (pool) {
if (mills <= 0) {
while (pool.isEmpty()) {
pool.wait();//一直等带release-》Notify
}
return pool.removeFirst();//得到一个connection
} else {
long future = System.currentTimeMillis() + mills;
long remaining = mills;
while (pool.isEmpty() && remaining > 0) {//基于时间进行等待,一直到超时。
pool.wait();
remaining = future - System.currentTimeMillis();
}
Connection result = null;
if (!pool.isEmpty()) {
result = pool.removeFirst();
}
return result;
}
}
}
}

两点:

  1. 对象的wait和notify
  2. 基于超时时间的等待。

测试:


package tread.demo.threadpool;

import java.sql.Connection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger; public class ConnectionPoolTest {
static ConnectionPool pool = new ConnectionPool(10);
static CountDownLatch start = new CountDownLatch(1);
static CountDownLatch end; public static void main(String[] args) throws Exception {
int threadCount = 1000;
end = new CountDownLatch(threadCount);
int count = 20;
AtomicInteger got = new AtomicInteger();
AtomicInteger notGot = new AtomicInteger();
for (int i = 0; i < threadCount; i++) {
Thread thread = new Thread(new ConnectionRunner(count, got, notGot), "ConnectionRunnerThread");
thread.start();
}
start.countDown();//tart的CountDown为0,保证了所有线程同时执行。
end.await();//等待所有线程执行完毕,
System.out.println("total invoke: " + (threadCount * count));
System.out.println("got connection: " + got);
System.out.println("not got connection: " + notGot); } static class ConnectionRunner implements Runnable {
int count;
AtomicInteger got;
AtomicInteger notGot; public ConnectionRunner(int count, AtomicInteger got, AtomicInteger notGot) {
this.count = count;
this.got = got;
this.notGot = notGot;
} public void run() {
try {
start.await();//等待start的CountDown为0.
} catch (InterruptedException e) {
e.printStackTrace();
}
while (count > 0) {
try {
Connection connection = pool.fetchConnection(1);//超时时间
if (connection != null) {
try {
connection.createStatement();
} finally {
pool.releaseConnection(connection);
got.incrementAndGet();
}
} else {
notGot.incrementAndGet();
}
} catch (Exception ex) {
} finally {
count--;
}
}
end.countDown();
}
}
}

继续巧用了CatdownLatch

结果:

total invoke: 20000
got connection: 11914
not got connection: 8086

如果调整超时时间,调整为100ms

结果如下(大部分时候都能得到connection)

total invoke: 20000
got connection: 19050
not got connection: 950

最新文章

  1. Redis处理文件日志并发(2)
  2. Machine Learning in Action -- 回归
  3. 解决jQuery插件sliderjs, 点击插件分页,导航按钮后不能重新开始.
  4. C++模板类中使用静态成员变量(例如Singleton模式)
  5. jQuery事件大全
  6. 从一开始,说出事java匿名内部类
  7. 深入了解C++中间mutablekeyword
  8. STM32—无需中断来实现使用DMA接收串口数据
  9. substance在java swing中使用注意事项
  10. CodeChef Cards, bags and coins [DP 泛型背包]
  11. 编译预处理命令define
  12. ML.NET 示例:聚类之客户细分
  13. Activemq -- Spring 整合
  14. Fluxion无线攻击
  15. AutoIt介绍
  16. Python-bootstrap
  17. java EE第一周博客
  18. BZOJ.2595.[WC2008]游览计划(DP 斯坦纳树)
  19. static 成员函数
  20. struct的使用

热门文章

  1. 解决PEnetwork启动的时候提示&quot;An error occured while starting the &quot;TCP/IP Registry Compatibility&quot; Service (2)!&quot;程序将立即退出的问题
  2. CSP-S考前救急(考试前还是别复习了,事实证明复习了也没考到...
  3. Pytorch循环神经网络LSTM时间序列预测风速
  4. mysql增加字段,修改字段,增加索引等语句
  5. 阅读java编程思想之一切都是对象
  6. SpringBoot第十九篇:邮件服务
  7. go-gin-api 规划目录和参数验证(二)
  8. Django-orm高级
  9. Mysql char(10) 与 varchar(10)的区别
  10. golang --os系统包详解