对象池设计模式


对象池设计模式是一种在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编程中用于处理昂贵的对象,例如数据库连接和网络连接。它与享元模式和单例模式相似,但具有不同的目的。

更新于:2023年8月1日

1000+ 次浏览

启动您的职业生涯

通过完成课程获得认证

开始学习
广告
© . All rights reserved.