对象池设计模式

javaobject oriented programmingprogramming更新于 2024/11/8 18:20:17

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() {
      // 创建并返回一个新的对象实例
      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() {
      // 创建并返回一个新的对象实例
      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);
   }
}

在此实现中,使用静态最终实例变量来急切初始化对象池。底层数据结构是 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() {
      // 创建并返回一个新的对象实例
      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 编程中,以处理数据库连接和网络连接等昂贵的对象。它与享元型和单例设计模式类似,但目的不同。


相关文章


有用资源