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));
}
}

java对象池化技术的更多相关文章

  1. 对象池化技术 org.apache.commons.pool

    恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率.Jakarta Commons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以 ...

  2. Java对象池技术的原理及其实现

    看到一片有关于java 对象基础知识,故转载一下,同时学习一下. 摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术时所应注意的问题. 关键词 对象池 ...

  3. Java--对象池化技术 org.apache.commons.pool2.ObjectPool

    org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...

  4. Java 数据持久化系列之池化技术

    在上一篇文章<Java 数据持久化系列之JDBC>中,我们了解到使用 JDBC 创建 Connection 可以执行对应的SQL,但是创建 Connection 会消耗很多资源,所以 Ja ...

  5. java对象池commons-pool-1.6详解(一)

    自己的项目中用到了 对象池 commons-pool: package com.sankuai.qcs.regulation.protocol.client; import com.dianping. ...

  6. Java对象池

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  7. Java对象池示例

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  8. commons-pool2 池化技术探究

    一.前言 我们经常会接触各种池化的技术或者概念,包括对象池.连接池.线程池等,池化技术最大的好处就是实现对象的重复利用,尤其是创建和使用大对象或者宝贵资源(HTTP连接对象,MySQL连接对象)等方面 ...

  9. 《Mybatis 手撸专栏》第6章:数据源池化技术实现

    作者:小傅哥 博客:https://bugstack.cn - 手写Mybatis系列文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 码农,只会做不会说? 你有发现吗,其实很大一部分码农 ...

随机推荐

  1. 【JZOJ6213】【20190613】String

    题目 \(n \le 10^{18} \ , \ |T| \le 10^5\) 题解 显然,最少的操作次数一定是贪心地能匹配就匹配 我们可以建出\(T\)的SAM,把SAM不能走的边补到根的后继节点 ...

  2. 洛谷 P5614题解

    吐槽:数据好像有点水,直接枚举到200可以得80 points. 另:我还是太弱了,比赛的时候只有90 points,#7死卡不过去,最后发现是没有判断 \(z_1\) 和 \(z_2\) 的范围-- ...

  3. c++ map内置类型的默认值(std::map default value for build-in type)

    大神的帖子,留着自己备忘:http://www.it1352.com/455626.html 结论:你看到的value是整数.浮点(初始化为零)的行为是由标准定义的,你可以依赖它. 网上还有好多帖子说 ...

  4. KD-Tree总结

    KD-Tree总结 问题引入 平面上有\(n\)个点,\(q\)组询问,每一次查询距离\((x,y)\)最近的点对,强制在线. 问题解决 暴力 显然我们可以直接枚举点然后算距离取\(min\),这样子 ...

  5. oracle 使用length()函数需要注意的坑!

      1.情景展示 筛选出指定字段字符长度既不等于18也不等于15的数据. 2.原因分析 第一步:按字符串度进行分组统计: 第二步:筛选数据. 你会发现,只将length=17统计了出来,长度不存在的数 ...

  6. kubernetes --- Glusterfs

    gluster配额管理gluster volume quota cloud enablegluster volume quota cloud limit-usage /mail/pbs 20MBdd ...

  7. Java编程思想之五初始化与清理

    随着计算机革命的发展,"不安全"的编程方式已经逐渐称为编程代价高昂的主因之一. 初始化和清理正是涉及安全的两个问题. 5.1 用构造器确保初始化 通过提供构造器,类的设计者可确保每 ...

  8. template cannot be keyed. Place the key on real elements instead.

    template cannot be keyed. Place the key on real elements instead. 一.总结 一句话总结: 原因:vue不支持在 template 元素 ...

  9. Python开源项目Top30

    原文地址:https://www.cnblogs.com/stoker/p/9101825.html No 1:Home-assistant (v0.6+) 基于Python 3的开源家庭自动化平台[ ...

  10. 安全漏洞XSS、CSRF、SQL注入以及DDOS攻击

    随着互联网的普及,网络安全变得越来越重要,程序员需要掌握最基本的web安全防范,下面列举一些常见的安全漏洞和对应的防御措施. 0x01: XSS漏洞 1.XSS简介 跨站脚本(cross site s ...