Skip to content

Commit 276700c

Browse files
committed
feat: 增加Java 中的对象池化 (https://www.wdbyte.com/java/object-pool.html)
1 parent c881767 commit 276700c

7 files changed

Lines changed: 355 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<module>junit5-jupiter-starter</module>
1414
<module>apache-httpclient</module>
1515
<module>leetcode</module>
16+
<module>tool-java-object-pool</module>
1617
</modules>
1718
<name>parent-modules</name>
1819
<description>Parent for all java modules</description>

tool-java-object-pool/pom.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>parent-modules</artifactId>
7+
<groupId>com.wdbyte</groupId>
8+
<version>1.0.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
<artifactId>objectpool</artifactId>
12+
13+
<properties>
14+
<maven.compiler.source>8</maven.compiler.source>
15+
<maven.compiler.target>8</maven.compiler.target>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.apache.commons</groupId>
21+
<artifactId>commons-pool2</artifactId>
22+
<version>2.11.1</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.openjdk.jmh</groupId>
26+
<artifactId>jmh-core</artifactId>
27+
<version>1.33</version>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.openjdk.jmh</groupId>
31+
<artifactId>jmh-generator-annprocess</artifactId>
32+
<version>1.33</version>
33+
<scope>provided</scope>
34+
</dependency>
35+
<dependency>
36+
<groupId>redis.clients</groupId>
37+
<artifactId>jedis</artifactId>
38+
<version>4.2.0</version>
39+
</dependency>
40+
</dependencies>
41+
</project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.wdbyet.tool.objectpool;
2+
3+
import redis.clients.jedis.Jedis;
4+
import redis.clients.jedis.JedisPool;
5+
6+
/**
7+
* @author https://www.wdbyte.com
8+
* @date 2022/07/09
9+
*/
10+
public class JedisPoolTest {
11+
12+
public static void main(String[] args) {
13+
JedisPool jedisPool = new JedisPool("localhost", 6379);
14+
// 从对象池中借一个对象
15+
Jedis jedis = jedisPool.getResource();
16+
String name = jedis.get("name");
17+
System.out.println("redis get :" + name);
18+
jedis.close();
19+
// 彻底退出前,关闭 Redis 连接池
20+
jedisPool.close();
21+
}
22+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.wdbyet.tool.objectpool.apachekeyedpool;
2+
3+
import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
4+
import org.apache.commons.pool2.KeyedPooledObjectFactory;
5+
import org.apache.commons.pool2.PooledObject;
6+
import org.apache.commons.pool2.impl.AbandonedConfig;
7+
import org.apache.commons.pool2.impl.DefaultPooledObject;
8+
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
9+
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
10+
import redis.clients.jedis.Jedis;
11+
12+
/**
13+
* @author https://www.wdbyte.com
14+
* @date 2022/07/07
15+
*/
16+
public class ApacheKeyedPool {
17+
18+
public static void main(String[] args) throws Exception {
19+
String key = "local";
20+
MyGenericKeyedObjectPool objectMyObjectPool = new MyGenericKeyedObjectPool(new MyKeyedPooledObjectFactory());
21+
Jedis jedis = objectMyObjectPool.borrowObject(key);
22+
String name = jedis.get("name");
23+
System.out.println("redis get :" + name);
24+
objectMyObjectPool.returnObject(key, jedis);
25+
}
26+
}
27+
28+
class MyKeyedPooledObjectFactory extends BaseKeyedPooledObjectFactory<String, Jedis> {
29+
30+
@Override
31+
public Jedis create(String key) throws Exception {
32+
if ("local".equals(key)) {
33+
return new Jedis("localhost", 6379);
34+
}
35+
if ("remote".equals(key)) {
36+
return new Jedis("192.168.0.105", 6379);
37+
}
38+
return null;
39+
}
40+
41+
@Override
42+
public PooledObject<Jedis> wrap(Jedis value) {
43+
return new DefaultPooledObject<>(value);
44+
}
45+
}
46+
47+
class MyGenericKeyedObjectPool extends GenericKeyedObjectPool<String, Jedis> {
48+
49+
public MyGenericKeyedObjectPool(KeyedPooledObjectFactory<String, Jedis> factory) {
50+
super(factory);
51+
}
52+
53+
public MyGenericKeyedObjectPool(KeyedPooledObjectFactory<String, Jedis> factory,
54+
GenericKeyedObjectPoolConfig<Jedis> config) {
55+
super(factory, config);
56+
}
57+
58+
public MyGenericKeyedObjectPool(KeyedPooledObjectFactory<String, Jedis> factory,
59+
GenericKeyedObjectPoolConfig<Jedis> config, AbandonedConfig abandonedConfig) {
60+
super(factory, config, abandonedConfig);
61+
}
62+
}
63+
64+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.wdbyet.tool.objectpool.apachepool;
2+
3+
import org.apache.commons.pool2.BasePooledObjectFactory;
4+
import org.apache.commons.pool2.PooledObject;
5+
import org.apache.commons.pool2.PooledObjectFactory;
6+
import org.apache.commons.pool2.impl.AbandonedConfig;
7+
import org.apache.commons.pool2.impl.DefaultPooledObject;
8+
import org.apache.commons.pool2.impl.GenericObjectPool;
9+
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
10+
import redis.clients.jedis.Jedis;
11+
12+
/**
13+
* @author https://www.wdbyte.com
14+
* @date 2022/07/07
15+
*/
16+
public class ApachePool {
17+
18+
public static void main(String[] args) throws Exception {
19+
MyGenericObjectPool objectMyObjectPool = new MyGenericObjectPool(new MyPooledObjectFactory());
20+
Jedis jedis = objectMyObjectPool.borrowObject();
21+
String name = jedis.get("name");
22+
System.out.println("redis get:" + name);
23+
objectMyObjectPool.returnObject(jedis);
24+
objectMyObjectPool.close();
25+
}
26+
27+
}
28+
29+
class MyPooledObjectFactory implements PooledObjectFactory<Jedis> {
30+
31+
@Override
32+
public void activateObject(PooledObject<Jedis> pooledObject) throws Exception {
33+
34+
}
35+
36+
@Override
37+
public void destroyObject(PooledObject<Jedis> pooledObject) throws Exception {
38+
Jedis jedis = pooledObject.getObject();
39+
jedis.close();
40+
System.out.println("释放连接");
41+
}
42+
43+
@Override
44+
public PooledObject<Jedis> makeObject() throws Exception {
45+
return new DefaultPooledObject(new Jedis("localhost", 6379));
46+
}
47+
48+
@Override
49+
public void passivateObject(PooledObject<Jedis> pooledObject) throws Exception {
50+
51+
}
52+
53+
@Override
54+
public boolean validateObject(PooledObject<Jedis> pooledObject) {
55+
return false;
56+
}
57+
}
58+
59+
class SimplePooledObjectFactory extends BasePooledObjectFactory<Jedis> {
60+
61+
@Override
62+
public Jedis create() throws Exception {
63+
return new Jedis("127.0.0.1", 6379);
64+
}
65+
66+
@Override
67+
public PooledObject<Jedis> wrap(Jedis jedis) {
68+
return new DefaultPooledObject<>(jedis);
69+
}
70+
}
71+
72+
class MyGenericObjectPool extends GenericObjectPool<Jedis> {
73+
74+
public MyGenericObjectPool(PooledObjectFactory factory) {
75+
super(factory);
76+
}
77+
78+
public MyGenericObjectPool(PooledObjectFactory factory, GenericObjectPoolConfig config) {
79+
super(factory, config);
80+
}
81+
82+
public MyGenericObjectPool(PooledObjectFactory factory, GenericObjectPoolConfig config,
83+
AbandonedConfig abandonedConfig) {
84+
super(factory, config, abandonedConfig);
85+
}
86+
}
87+
88+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.wdbyet.tool.objectpool.mypool;
2+
3+
import java.io.Closeable;
4+
import java.io.IOException;
5+
import java.util.HashSet;
6+
import java.util.Stack;
7+
8+
/**
9+
* @author https://www.wdbyte.com
10+
*/
11+
public class MyObjectPool<T extends Closeable> {
12+
13+
// 池子大小
14+
private Integer size = 5;
15+
// 对象池栈。后进先出
16+
private Stack<T> stackPool = new Stack<>();
17+
// 借出的对象的 hashCode 集合
18+
private HashSet<Integer> borrowHashCodeSet = new HashSet<>();
19+
20+
/**
21+
* 增加一个对象
22+
*
23+
* @param t
24+
*/
25+
public synchronized void addObj(T t) {
26+
if ((stackPool.size() + borrowHashCodeSet.size()) == size) {
27+
throw new RuntimeException("池中对象已经达到最大值");
28+
}
29+
stackPool.add(t);
30+
System.out.println("添加了对象:" + t.hashCode());
31+
}
32+
33+
/**
34+
* 借出一个对象
35+
*
36+
* @return
37+
*/
38+
public synchronized T borrowObj() {
39+
if (stackPool.isEmpty()) {
40+
System.out.println("没有可以被借出的对象");
41+
return null;
42+
}
43+
T pop = stackPool.pop();
44+
borrowHashCodeSet.add(pop.hashCode());
45+
System.out.println("借出了对象:" + pop.hashCode());
46+
return pop;
47+
}
48+
49+
/**
50+
* 归还一个对象
51+
*
52+
* @param t
53+
*/
54+
public synchronized void returnObj(T t) {
55+
if (borrowHashCodeSet.contains(t.hashCode())) {
56+
stackPool.add(t);
57+
borrowHashCodeSet.remove(t.hashCode());
58+
System.out.println("归还了对象:" + t.hashCode());
59+
return;
60+
}
61+
throw new RuntimeException("只能归还从池中借出的对象");
62+
}
63+
64+
/**
65+
* 销毁池中对象
66+
*/
67+
public synchronized void destory() {
68+
if (!borrowHashCodeSet.isEmpty()) {
69+
throw new RuntimeException("尚有未归还的对象,不能关闭所有对象");
70+
}
71+
while (!stackPool.isEmpty()) {
72+
T pop = stackPool.pop();
73+
try {
74+
pop.close();
75+
} catch (IOException e) {
76+
throw new RuntimeException(e);
77+
}
78+
}
79+
System.out.println("已经销毁了所有对象");
80+
}
81+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.wdbyet.tool.objectpool.mypool;
2+
3+
import org.openjdk.jmh.annotations.Benchmark;
4+
import org.openjdk.jmh.annotations.Measurement;
5+
import org.openjdk.jmh.annotations.Scope;
6+
import org.openjdk.jmh.annotations.State;
7+
import org.openjdk.jmh.annotations.Warmup;
8+
import org.openjdk.jmh.infra.Blackhole;
9+
import redis.clients.jedis.Jedis;
10+
11+
/**
12+
* @author https://www.wdbyte.com
13+
* @date 2022/07/02
14+
*/
15+
@State(Scope.Benchmark)
16+
@Warmup(iterations = 1, time = 3)
17+
@Measurement(iterations = 3, time = 3)
18+
public class MyObjectPoolTest {
19+
private static MyObjectPool<Jedis> objectPool = new MyObjectPool<>();
20+
21+
static {
22+
//objectPool.addObj(new Jedis("192.168.0.105", 6379));
23+
}
24+
25+
public static void main(String[] args) {
26+
MyObjectPool<Jedis> objectPool = new MyObjectPool<>();
27+
// 增加一个 jedis 连接对象
28+
objectPool.addObj(new Jedis("127.0.0.1", 6379));
29+
objectPool.addObj(new Jedis("127.0.0.1", 6379));
30+
// 从对象池中借出一个 jedis 对象
31+
Jedis jedis = objectPool.borrowObj();
32+
// 一次 redis 查询
33+
String name = jedis.get("name");
34+
System.out.println(String.format("redis get:" + name));
35+
// 归还 redis 连接对象
36+
objectPool.returnObj(jedis);
37+
// 销毁对象池中的所有对象
38+
objectPool.destory();
39+
// 再次借用对象
40+
objectPool.borrowObj();
41+
}
42+
43+
@Benchmark
44+
public void testPool(Blackhole bh) {
45+
Jedis jedis = objectPool.borrowObj();
46+
String name = jedis.get("name");
47+
objectPool.returnObj(jedis);
48+
bh.consume(name);
49+
}
50+
51+
@Benchmark
52+
public void test(Blackhole bh) {
53+
Jedis jedis = new Jedis("localhost", 6379);
54+
String name = jedis.get("name");
55+
jedis.close();
56+
bh.consume(name);
57+
}
58+
}

0 commit comments

Comments
 (0)