物件池設計模式


物件池設計模式是一種在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+ 次瀏覽

啟動您的職業生涯

透過完成課程獲得認證

開始學習
廣告