Java 对象池设计模式
在Java编程中经常使用的一种软件设计模式是对象池设计模式,它用于最大化对象的利用率。该模式控制池中项目的创建和销毁。
对象的生产和销毁管理是通过对象池设计模式来完成的。该模式的概念是累积可重用的对象,而不是每次需要对象时都创建新的对象。对于需要生产新对象成本昂贵的情况,例如网络连接、数据库连接或昂贵对象,Java程序员经常使用对象池设计模式。
对象池设计的语法
Java中的对象池设计模式具有以下语法-
- 创建一个固定大小的对象集合。
-
初始化池中的项目。
-
跟踪当前在池中的项目。
-
在需要时检查池中是否有可用对象。
-
请务必立即检索池中的任何可用对象,并根据需要适当地返回。
-
然而,如果当前池中没有任何可访问的项目-我们请求立即创建一个新项目,以免浪费时间或资源,然后将其返回到循环中。
对象池设计的不同算法
Java对象池设计模式可以使用各种算法。以下是三种可能的策略,每种策略都有一个独特的代码实现-
懒惰初始化和同步
import java.util.ArrayList;
import java.util.List;
public class ObjectPool {
private static ObjectPool instance;
private List<Object> pool = new ArrayList<>();
private int poolSize;
private ObjectPool() {}
public static synchronized ObjectPool getInstance(int poolSize) {
if (instance == null) {
instance = new ObjectPool();
instance.poolSize = poolSize;
for (int i = 0; i < poolSize; i++) {
instance.pool.add(createObject());
}
}
return instance;
}
private static Object createObject() {
// Create and return a new object instance
return new Object();
}
public synchronized Object getObject() {
if (pool.isEmpty()) {
return createObject();
} else {
return pool.remove(pool.size() - 1);
}
}
public synchronized void releaseObject(Object object) {
if (pool.size() < poolSize) {
pool.add(object);
}
}
}
在这里使用的技术通过初始化具有预设容量限制的懒加载和同步对象池来强调线程安全性,这些容量限制可以扩展。空的池会安全地生成新实例,而非满的实例会被谨慎地重新引入以保持正确的操作完整性。
使用并发数据结构进行急切初始化
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ObjectPool {
private static final int POOL_SIZE = 10;
private static ObjectPool instance = new ObjectPool();
private BlockingQueue<Object> pool = new LinkedBlockingQueue<>(POOL_SIZE);
private ObjectPool() {
for (int i = 0; i < POOL_SIZE; i++) {
pool.offer(createObject());
}
}
private static Object createObject() {
// Create and return a new object instance
return new Object();
}
public static ObjectPool getInstance() {
return instance;
}
public Object getObject() throws InterruptedException {
return pool.take();
}
public void releaseObject(Object object) {
pool.offer(object);
}
}
在这个实现中,使用静态的final实例变量来及早初始化对象池。底层的数据结构是一个LinkedBlockingQueue,它提供了线程安全而无需同步的功能。在初始化过程中,对象被添加到池中,当需要时使用take()从队列中检索它们。当一个项被释放时,使用offer()重新排队它。
基于时间的过期
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class ObjectPool {
private static final int POOL_SIZE = 10;
private static ObjectPool instance = new ObjectPool();
private BlockingQueue<Object> pool = new LinkedBlockingQueue<>(POOL_SIZE);
private ObjectPool() {}
private static Object createObject() {
// Create and return a new object instance
return new Object();
}
public static ObjectPool getInstance() {
return instance;
}
public Object getObject() throws InterruptedException {
Object object = pool.poll(100, TimeUnit.MILLISECONDS);
if (object == null) {
object = createObject();
}
return object;
}
public void releaseObject(Object object) {
pool.offer(object);
}
}
在这个版本中,对象池采用了基于时间的到期机制,而不是固定大小。当需要一个对象时,使用poll()函数从池中获取,如果没有可用对象,则等待一段时间后返回null。对象是按需生成的。如果没有对象的话,将生成一个新的对象并返回。当释放一个对象时,使用offer()将其放回池中。根据提供的超时值,使用expireObjects()函数从池中移除已过期的物品。
使用对象池设计模式的不同方法
Java的对象池设计模式可以通过多种方式实现。下面是两种典型的方法,包括代码示例和结果 –
方法1:简单的对象池设计模式
构建一个简单而实用的对象池方法之一是使用基于数组的方法。下面是这种方法的工作原理 – 所有对象在生成后都会完全包括在相应的“池”数组中以供将来使用;在运行时需要时,会检查这个集合中是否有所需的任何项目。如果可以从现有库存中获得,则立即返回;否则按需生成另一个新对象。
示例
public class ObjectPool {
private static final int POOL_SIZE = 2;
private static List<Object> pool = new ArrayList<Object>(POOL_SIZE);
static {
for(int i = 0; i < POOL_SIZE; i++) {
pool.add(new Object());
}
}
public static synchronized Object getObject() {
if(pool.size() > 0) {
return pool.remove(0);
} else {
return new Object();
}
}
public static synchronized void releaseObject(Object obj) {
pool.add(obj);
}
}
示例
public class ObjectPoolExample {
public static void main(String[] args) {
Object obj1 = ObjectPool.getObject();
Object obj2 = ObjectPool.getObject();
System.out.println("Object 1: " + obj1.toString());
System.out.println("Object 2: " + obj2.toString());
ObjectPool.releaseObject(obj1);
ObjectPool.releaseObject(obj2);
Object obj3 = ObjectPool.getObject();
Object obj4 = ObjectPool.getObject();
System.out.println("Object 3: " + obj3.toString());
System.out.println("Object 4: " + obj4.toString());
}
}
输出
Object 1: java.lang.Object@4fca772d
Object 2: java.lang.Object@1218025c
Object 3: java.lang.Object@4fca772d
Object 4: java.lang.Object@1218025c
方法2:通用对象池设计模式
使用列表作为基础,这种技术方便地构建了一个标准的对象池,它存储对象,直到它们完全生产完成并包含在集合中。每当需要访问一个项目时,系统会浏览对象池以寻找可以使用的可能选项。如果找到可用的选项,则使用它就足够了;但如果没有可用选项,则必须创建另一个新项目。
示例
import java.util.ArrayList;
import java.util.List;
public class ObjectPool<T> {
private List<T> pool;
public ObjectPool(List<T> pool) {
this.pool = pool;
}
public synchronized T getObject() {
if (pool.size() > 0) {
return pool.remove(0);
} else {
return createObject();
}
}
public synchronized void releaseObject(T obj) {
pool.add(obj);
}
private T createObject() {
T obj = null;
// create object code here
return obj;
}
public static void main(String[] args) {
List<String> pool = new ArrayList<String>();
pool.add("Object 1");
pool.add("Object 2");
ObjectPool<String> objectPool = new ObjectPool<String>(pool);
String obj1 = objectPool.getObject();
String obj2 = objectPool.getObject();
System.out.println("Object 1: " + obj1);
System.out.println("Object 2: " + obj2);
objectPool.releaseObject(obj1);
objectPool.releaseObject(obj2);
String obj3 = objectPool.getObject();
String obj4 = objectPool.getObject();
System.out.println("Object 3: " + obj3);
System.out.println("Object 4: " + obj4);
}
}
输出
Object 1: Object 1
Object 2: Object 2
Object 3: Object 1
Object 4: Object 2
使用类级锁的最佳实践
当创建新对象的成本较高时,Java程序员经常使用对象池设计模式。典型的使用场景包括:
网络连接
在Java程序中,可以使用对象池设计模式来管理网络连接。与每次需要时创建新连接相比,最好是从池中重用现有连接。这可以增强应用程序的功能,同时减轻网络服务器的负担。
数据库连接
类似于管理网络连接的方式,Java应用程序也可以使用对象池设计模式来处理数据库连接。与每次需要数据库连接时创建新连接相比,最好是重用池中的现有连接。这可以提高应用程序的性能,同时减轻数据库服务器的负担。
线程池
在使用Java程序的开发者应该作为一种有效管理线程池的方法来应用对象池设计模式。以重用预先存在的线程为基础的合理使用,可以在指定的工作组中重复使用线程,而不是根据需要重新创建每个所需的线程。因此,它通过保持线程创建和终止过程的开销较低,以此结构的效率来鼓励最佳应用程序性能。
图像处理
在处理密集的图像处理任务时,考虑在基于Java的程序中实现对象池设计模式。通过利用来自专用池的预先存在的对象,您可以加快应用程序的性能,同时减少对图片编辑任务的计算要求。
文件系统操作
如果在Java应用程序中面临要求苛刻的图像处理任务,值得考虑应用对象池设计模式。该技术利用特定池中的现有项来增强程序的输出速度,并减少编辑照片所需的总体计算资源。
结论
对象池设计模式是Java编程中一种有用的设计模式,适用于创建新对象成本较高的情况。它提供了一种控制可重用对象的方法,降低了创建新产品的总成本。简单对象池和通用对象池是对象池设计模式的两个实现示例。对象池设计模式通常应用于处理类似数据库连接和网络连接等昂贵的对象的Java编程。它具有不同的目的,但与享元模式和单例模式类似。