https://blog.csdn.net/tiane5hao/article/details/85957840

对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁分配、释放所造成的问题的。把该模式应用到数据库连接管理领域,就是建立一个数据库连接池,提供一套高效的连接分配、使用策略,最终目标是实现连接的高效、安全的复用。还有一类对象池大家可能不太了解,对于nio中有个堆外内存,netty的ByteBuf对象的实现就是一个可复用的对象池来提高性能。连接池大家平时听的多,使用也多,但是自己实现应该比较少。

先写一个简单通用的对象池

总共包含几个类,代码如下:
ICommonPool : 定义通用池,借出对象和归还对象
PoolFactory :对象工厂,负责创建和销毁对象
PoolConfig : 对象池的配置(最大连接数和最小连接数)
BaseCommonPool :对象池的主要基础实现

// An highlighted block
package test.pool; /**
* 通用池接口定义
* @param <T>
*/
public interface ICommonPool<T> {
/**
* 租借对象
*/
T borrowObject() throws Exception; /**
* 返回对象池
*/
void returnObject(T object) throws Exception;
}

package test.pool;


/**
* 负责创建、销毁对象
* @param <T>
*/
public interface PoolFactory<T> { /**
* 创建对象
* @return
*/
T makeObject(); /**
* 销毁对象
*/
void destroyObject();
}
package test.pool;

/**
* 对象池配置
*/
public class PoolConfig { // 池中最大对象
private int maxTotal = 8;
//初始化对象数
private int minTotal = 0; public int getMaxTotal() {
return maxTotal;
} public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
} public int getMinTotal() {
return minTotal;
} public void setMinTotal(int minTotal) {
this.minTotal = minTotal;
}
}
package test.pool;

import java.util.concurrent.LinkedBlockingQueue;
/**
* 对象池的基础实现
* 这里用阻塞队列来实现
* @param <T>
*/
public class BaseCommonPool<T> implements ICommonPool<T> { private LinkedBlockingQueue<T> pool; private PoolConfig poolConfig;
private PoolFactory<T> poolFactory; public BaseCommonPool(PoolConfig poolConfig, PoolFactory<T> poolFactory){
this.poolConfig = poolConfig;
this.poolFactory = poolFactory;
initCommonPool();
} private void initCommonPool() {
//代表池的大小
pool = new LinkedBlockingQueue<T>(poolConfig.getMaxTotal());
while (poolConfig.getMinTotal() > pool.size()){
T obj = poolFactory.makeObject();
pool.offer(obj);
}
} /**
* 租借对象
*/
public T borrowObject() throws Exception{
//如果队列中对象为空,poll方法返回null,非阻塞(take方法阻塞)
T obj = pool.poll();
if(obj != null){
return obj;
}
return poolFactory.makeObject();
} /**
* 返回对象池
*/
public void returnObject(T object) throws Exception{
//offer方法非阻塞,如果队列满了,直接抛弃,返回false,与put方法的区别自行百度
if(!pool.offer(object)){
poolFactory.destroyObject();
}
}
}

通过上面的通用池实现jedis连接池

实现类如下:
MyRedisFactory : jedis的对象工厂
MyRedisPool : jedis连接池

jedis pom依赖

 <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
package test.objectpool;

import redis.clients.jedis.Jedis;
import test.pool.PoolFactory; public class MyRedisFactory implements PoolFactory<Jedis> { public MyRedisFactory() {
} public Jedis makeObject() {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.connect();
return jedis;
} public void destroyObject(Jedis jedis) {
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception var4) {
;
} jedis.disconnect();
} catch (Exception var5) {
;
}
}
} }
package test.objectpool;

import redis.clients.jedis.Jedis;
import test.pool.BaseCommonPool;
import test.pool.PoolConfig; public class MyRedisPool extends BaseCommonPool<Jedis> { public MyRedisPool(PoolConfig config) {
super( config, new MyRedisFactory());
}
}

连接池测试

下面是jedis连接池和非连接池的测试(单线程),对于多线程后续测试了再补上,测试执行1万次本地redis方法get耗时比对结果如下:
线程池执行耗时1153 ms
创建redis执行耗时5437 ms
性能有着明显的提升

package test.objectpool;

import redis.clients.jedis.Jedis;
import test.pool.PoolConfig; public class PoolTest { public static void main(String[] args) {
PoolConfig poolConfig = new PoolConfig();
poolConfig.setMaxTotal(8);
poolConfig.setMinTotal(4);
MyRedisPool myRedisPool = new MyRedisPool(poolConfig); //线程池执行
long start = System.currentTimeMillis();
for(int i = 0; i < 10000; i++){
Jedis jedis = null;
try {
jedis = myRedisPool.borrowObject();
String result = jedis.get("aaa");
// System.out.println(result);
}catch (Exception e){
e.printStackTrace();
}finally {
myRedisPool.returnObject(jedis);
}
}
System.out.println("线程池执行耗时" + (System.currentTimeMillis() - start)); //创建redis执行
start = System.currentTimeMillis();
for(int i = 0; i < 10000; i++){
Jedis jedis = null;
try {
jedis = new Jedis("127.0.0.1", 6379);
String result = jedis.get("aaa");
// System.out.println(result);
}catch (Exception e){
e.printStackTrace();
}finally {
jedis.close();
}
}
System.out.println("创建redis执行耗时" + (System.currentTimeMillis() - start));
}
}

最新文章

  1. [译]:Xamarin.Android平台功能——位置服务
  2. *HDU 1385 最短路 路径
  3. 【转】Tomcat的默认访问路径
  4. AngularJS in Action读书笔记3——走近Services
  5. 浅谈mysql的两阶段提交协议
  6. HTML5中的文本级语义
  7. 设计模式之桥接模式(Bridge)
  8. 字符串(后缀自动机):USACO Dec10 恐吓信
  9. C# 基础概念之延迟加载
  10. 第一个VC++ win32程序 绘制简单图形
  11. 新发现IM项目Rabbitim(使用msys或者cygwin编译安装),FileZilla(wxWidget开发)
  12. Arduino LiquidCrystal Library Bug Report #174181
  13. jenkins插件安装与升级[三]
  14. 大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS
  15. vue-cil和webpack中本地静态图片的路径问题解决方案
  16. 关于 html input标签的几个常用操作
  17. centos6.8离线安装nginx
  18. python - beautifulsoup4模块
  19. Leetcode - 309. Best Time to Buy and Sell Stock with Cooldown
  20. css预处理器--sass学习($变量名)

热门文章

  1. 从WinDbg中的转储查看操作系统版本和SP详细信息
  2. linux 所有命令无法使用
  3. OpenFOAM——在钝板上分离的层流
  4. 在 Mac、Linux、Windows 下Go交叉编译
  5. php提示Notice: Undefined index解决方法
  6. PHP面试-复习知识点整理
  7. eventlet 模块搭建 WEB 服务器
  8. Cross-channel Communication Networks
  9. odoo开发笔记 -- 提高访问安全性的一种方式
  10. Ubuntu宝塔面板设置网站 Apache Server API为Apache 2.0 Handler模式