用java多线程模拟数据库连接池
2024-10-21 13:40:43
模拟一个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;
}
}
}
}
两点:
- 对象的wait和notify
- 基于超时时间的等待。
测试:
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
最新文章
- Redis处理文件日志并发(2)
- Machine Learning in Action -- 回归
- 解决jQuery插件sliderjs, 点击插件分页,导航按钮后不能重新开始.
- C++模板类中使用静态成员变量(例如Singleton模式)
- jQuery事件大全
- 从一开始,说出事java匿名内部类
- 深入了解C++中间mutablekeyword
- STM32—无需中断来实现使用DMA接收串口数据
- substance在java swing中使用注意事项
- CodeChef Cards, bags and coins [DP 泛型背包]
- 编译预处理命令define
- ML.NET 示例:聚类之客户细分
- Activemq -- Spring 整合
- Fluxion无线攻击
- AutoIt介绍
- Python-bootstrap
- java EE第一周博客
- BZOJ.2595.[WC2008]游览计划(DP 斯坦纳树)
- static 成员函数
- struct的使用
热门文章
- 解决PEnetwork启动的时候提示";An error occured while starting the ";TCP/IP Registry Compatibility"; Service (2)!";程序将立即退出的问题
- CSP-S考前救急(考试前还是别复习了,事实证明复习了也没考到...
- Pytorch循环神经网络LSTM时间序列预测风速
- mysql增加字段,修改字段,增加索引等语句
- 阅读java编程思想之一切都是对象
- SpringBoot第十九篇:邮件服务
- go-gin-api 规划目录和参数验证(二)
- Django-orm高级
- Mysql char(10) 与 varchar(10)的区别
- golang --os系统包详解