模拟一个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. 2019.11.12&13题解

    写在前面: 虽然拿到了rk1,但是T3被卡常TLE90分,(考后再交就A了!?),lemon80,又丢失了一次良好的AK机会, 掐头去尾距离联赛仅剩2天,最近中午一直睡不好,可能是有些紧张, 希望自己 ...

  2. PLSQL安装过程和SCOTT用户被锁的解决方法

    一.PLSQL安装: PLSQL基本就是一键式安装,没有什么需要修改的东西,一路Next就行了. 二.SCOTT用户被锁问题解决 1.问题如下: SCOTT用户默认是被锁的,需要通过system管理员 ...

  3. Kubernetes 学习(十)Kubernetes 容器持久化存储

    0. 前言 最近在学习张磊老师的 深入剖析Kubernetes 系列课程,最近学到了 Kubernetes 容器持久化存储部分 现对这一部分的相关学习和体会做一下整理,内容参考 深入剖析Kuberne ...

  4. SQLAIchemy(二)ORM 相关

    0. 前言 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 简单的说,ORM是通过使用描述对象和数据库之 ...

  5. nginx 目录自动加斜线”/”

    默认配置当你访问http://abc.example.com/dir 时不会加”/” 常见做法 if (-d $request_filename){  rewrite ^/(.*)([^/])$ ht ...

  6. .NET Core开发的iNeuOS物联网平台部署树霉派(raspbian),从网关到云端整体解决方案。助力2019中国.NET峰会。

    2019 中国.NET 开发者峰会正式启动 目       录 1.      概述... 2 2.      树莓派硬件配置... 2 3.      软件信息... 3 4.      Raspb ...

  7. POI 操作 excel表格 (简单整理)

    简单的整理: import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import ...

  8. Qt 简易图片播放器

    一.前言 使用 Qt 制作了一个简单的图片播放器,点击 "浏览按钮" 浏览图片所在目录,目录中的所有图片缩小图标和名称会显示在左侧的图片列表中,点击列表中的图片项,可以在右侧区域的 ...

  9. ReentrantReadWriteLock可重入,锁升级,锁降级

    public class ReentrantReadWriteLockTest { public static void main(String[] args) throws InterruptedE ...

  10. 排序算法Java代码实现(四)—— 归并排序

    本篇内容: 归并排序 归并排序 算法思想: 将两个或两个以上的有序表合并成一个新的有序表, 即把待排序序列分成若干个子序列,每个子序列是有序的,然后在把有序子序列合并为整体有序序列. 此算法分为两步: ...