模拟一个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

用java多线程模拟数据库连接池的更多相关文章

  1. java多线程模拟生产者消费者问题,公司面试常常问的题。。。

    package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...

  2. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  3. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  4. Java自学-JDBC 数据库连接池

    数据库连接池 与线程池类似的,数据库也有一个数据库连接池. 不过他们的实现思路是不一样的. 本章节讲解了自定义数据库连接池类:ConnectionPool,虽然不是很完善和健壮,但是足以帮助大家理解C ...

  5. java 多线程 4 线程池

    系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似 ...

  6. java多线程:线程池原理、阻塞队列

    一.线程池定义和使用 jdk 1.5 之后就引入了线程池. 1.1 定义 从上面的空间切换看得出来,线程是稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需 ...

  7. Java 多线程之线程池的使用

    一. 使用背景 谈到Java多线程,我们很自然的会想到并发,在编写多线程代码时,我们一般会创建多个线程,如果并发的线程数量很多,而且每个线程都是执行一个时间很短的任务就结束了,这样频繁的进行线程的创建 ...

  8. Java多线程:线程池

    一. 背景 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池可以对线程进行统一的分配.调优和监控,并有以下好处:     第一:降低资源消耗.通过重复利用已 ...

  9. java多线程、线程池及Spring配置线程池详解

    1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...

随机推荐

  1. Linux性能优化实战学习笔记:第六讲

    一.环境准备 1.安装软件包 终端1 机器配置:2 CPU,8GB 内存 预先安装 docker.sysstat.perf等工具 [root@luoahong ~]# docker -v Docker ...

  2. MySQL实战45讲学习笔记:第十二讲

    一.引子 平时的工作中,不知道你有没有遇到过这样的场景,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短. ...

  3. [LeetCode] 25. Reverse Nodes in k-Group 每k个一组翻转链表

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. k  ...

  4. docker for windows添加卷映射

    docker settings->share drivers 设置共享目录 启动docker时-v 指定目录 ··· docker run -v /d/temp:/app -it --rm co ...

  5. markdown格式接口文档模板

    源文件 https://files.cnblogs.com/files/bincoding/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3.zip 目录 测试接口 查询指定项 ...

  6. .NET Core:SignalR

    在Startup中的ConfigureServices方法中配置:services.AddSignalR(); 跨域设置中需要更改设置:services.AddCors(options => o ...

  7. 1+x证书《Web前端开发》等级考试样题

    Web前端开发初级理论考试样题2019 http://blog.zh66.club/index.php/archives/149/ Web前端开发初级实操考试样题2019 http://blog.zh ...

  8. Unity Shader 屏幕后效果——Bloom外发光

    Bloom的原理很简单,主要是提取渲染图像中的亮部区域,并对亮部区域进行模糊处理,再与原始图像混合而成. 一般对亮部进行模糊处理的部分采用高斯模糊,关于高斯模糊,详见之前的另一篇博客: https:/ ...

  9. HTML+css基础 表格标签table Table标签属性 td标签属性

    表格标签table:   他是由行与列构成,最小单位是单元格. 行标签  <tr></tr> 单元格标签<td></td> Table标签属性: Bor ...

  10. 集合类源码(二)Collection之List(ArrayList, LinkedList, Vector)

    ArrayList 功能 完全命名 public class ArrayList<E> extends AbstractList<E> implements List<E ...