Heim  >  Artikel  >  Java  >  Objektpool-Entwurfsmuster

Objektpool-Entwurfsmuster

WBOY
WBOYnach vorne
2023-08-19 16:29:21544Durchsuche

Objektpool-Entwurfsmuster

Ein in der Java-Programmierung häufig verwendetes Software-Designmuster ist das Objektpool-Designmuster. Dieser Modus steuert, wie Objekte im Objektpool erstellt und zerstört werden.

Verwenden Sie das Objektpool-Entwurfsmuster, um die Produktion und Zerstörung von Objekten zu verwalten. Das Konzept dieses Musters besteht darin, wiederverwendbare Objekte anzusammeln, anstatt jedes Mal, wenn sie benötigt werden, neue zu erstellen. In Situationen, in denen die Kosten für die Erstellung neuer Objekte erheblich sind, wie z. B. Netzwerkverbindungen, Datenbankverbindungen oder teure Objekte, verwenden Java-Programmierer häufig das Entwurfsmuster für Objektpools.

Syntax des Objektpooldesigns

In Java lautet die Syntax des Objektpool-Entwurfsmusters wie folgt: −

  • Erstellen Sie eine Objektsammlung mit fester Größe.

  • Initialisieren Sie die Poolelemente.

  • Verfolgen Sie derzeit im Pool befindliche Artikel.

  • Überprüfen Sie bei Bedarf, ob sich im Pool ein zugänglicher Gegenstand befindet.

  • Bitte stellen Sie sicher, dass Sie alle verfügbaren Gegenstände im Pool zeitnah selbst abholen und bei Bedarf ordnungsgemäß zurückgeben

  • Sollte jedoch derzeit kein Artikel in diesem Depot verfügbar sein, bitten wir darum, sofort einen neuen Artikel zu erstellen, um Zeit- oder Ressourcenverschwendung zu vermeiden, und ihn dann wieder in Umlauf zu bringen.

Verschiedene Algorithmen für das Design von Objektpools

Java-Objektpool-Entwurfsmuster können für verschiedene Algorithmen verwendet werden. Hier sind drei mögliche Strategien mit jeweils einzigartigen Code-Implementierungen:

Verzögerte Initialisierung und Synchronisierung

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);
      }
   }
}

Die hier verwendete Technik betont die Thread-Sicherheit durch die Initialisierung eines entsprechend verzögerten und synchronisierten Objektpools mit voreingestellten Kapazitätsbeschränkungen, die bei Erweiterung geändert werden können. Leere Pools führen zu einer sicheren Produktion neuer Instanzen, während nicht vollständige Instanzen sorgfältig wieder eingeführt werden, um die ordnungsgemäße Betriebsintegrität aufrechtzuerhalten .

Eifrige Initialisierung mit gleichzeitigen Datenstrukturen

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);
   }
}

In dieser Implementierung wird eine statische letzte Instanzvariable verwendet, um den Objektpool eifrig zu initialisieren. Die zugrunde liegende Datenstruktur ist eine LinkedBlockingQueue, die Thread-Sicherheit bietet, ohne dass eine Synchronisierung erforderlich ist. Während der Initialisierung werden Objekte zum Pool hinzugefügt und mit take() bei Bedarf aus der Warteschlange abgerufen. Wenn ein Artikel freigegeben wird, stellen Sie ihn mit offer() erneut in die Warteschlange.

Zeitbasierter Ablauf

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);
   }

}

Der Objektpool in dieser Version verwendet einen zeitbasierten Ablaufmechanismus anstelle einer festen Größe. Wenn ein Objekt benötigt wird, wird die Funktion poll() verwendet, um das Objekt aus dem Pool zu entfernen. Wenn kein Objekt verfügbar ist, wartet die Funktion eine Zeit lang und gibt dann null zurück. Objekte werden bei Bedarf generiert. Wenn kein Objekt vorhanden ist, wird ein neues Objekt generiert und zurückgegeben. Wenn ein Objekt freigegeben wird, verwenden Sie offer(), um es wieder in den Pool zu stellen. Die Funktion „expireObjects()“ wird verwendet, um abgelaufene Elemente basierend auf dem angegebenen Timeout-Wert aus dem Pool zu entfernen.

Verschiedene Möglichkeiten, das Objektpool-Entwurfsmuster zu verwenden

Das Objektpool-Entwurfsmuster von Java kann auf viele Arten implementiert werden. Nachfolgend finden Sie zwei typische Methoden, einschließlich Codebeispielen und Ergebnissen −

Methode 1: Einfaches Objektpool-Entwurfsmuster

Eine Möglichkeit, einen einfachen und praktischen Objektpool aufzubauen, besteht darin, einen Array-basierten Ansatz zu übernehmen. Dieser Ansatz funktioniert wie folgt: Sobald alle Objekte vollständig generiert sind, werden sie zur zukünftigen Verwendung in das entsprechende „Pool“-Array aufgenommen. Die Sammlung wird daraufhin überprüft, ob eines der erforderlichen Elemente verfügbar ist. Wenn es aus dem vorhandenen Bestand beschafft werden kann, wird es sofort zurückgegeben; andernfalls wird je nach Bedarf ein weiteres neues Objekt generiert.

Beispiel

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);
   }
}

Beispiel

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());
   }
}

Ausgabe

Object 1: java.lang.Object@4fca772d
Object 2: java.lang.Object@1218025c
Object 3: java.lang.Object@4fca772d
Object 4: java.lang.Object@1218025c

Methode 2: Universelles Objektpool-Entwurfsmuster

Diese Technik nutzt Listen als Basis und erleichtert den Aufbau eines Standardobjektpools, indem Objekte in der Sammlung gespeichert werden, bis sie vollständig generiert und in die Sammlung aufgenommen werden. Immer wenn Zugriff auf ein Element erforderlich ist, durchsucht das System die verfügbaren Optionen im Pool. Wenn eine Option verfügbar ist, reicht dies aus. Wenn jedoch keine verfügbar ist, müssen Sie ein weiteres neues Projekt erstellen.

Beispiel

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);
   }
}

Ausgabe

Object 1: Object 1
Object 2: Object 2
Object 3: Object 1
Object 4: Object 2

Best Practices für die Verwendung von Sperren auf Klassenebene

Java-Programmierer verwenden häufig das Objektpool-Entwurfsmuster, wenn die Kosten für die Herstellung neuer Objekte hoch sind. Zu den typischen Nutzungsszenarien gehören −

Internetverbindung

In einem Java-Programm können Netzwerkverbindungen mithilfe des Objektpool-Entwurfsmusters verwaltet werden. Es ist besser, vorhandene Verbindungen aus einem Pool wiederzuverwenden, anstatt jedes Mal neue erstellen zu müssen. Dies kann die Funktionalität der Anwendung verbessern und gleichzeitig vereinfachen Belastung des Netzwerkservers.

Datenbankverbindung

Ähnlich wie bei der Netzwerkverbindungsverwaltung können Java-Anwendungen auch das Objektpool-Entwurfsmuster verwenden, um Datenbankverbindungen zu verwalten. Es ist besser, eine vorhandene Verbindung aus dem Pool wiederzuverwenden, als jedes Mal, wenn eine Datenbankverbindung benötigt wird, eine neue zu erstellen. Dadurch kann die Anwendungsleistung verbessert und die Belastung des Datenbankservers verringert werden.

Thread-Pool

Entwickler, die Java-Programme verwenden, sollten das Objektpool-Entwurfsmuster übernehmen, um Thread-Pools effektiv zu verwalten. Anstatt jeden erforderlichen Thread nach Bedarf neu zu erstellen, beruht eine gut geplante Nutzung auf der Wiederverwendung bereits vorhandener Threads, die in einer bestimmten Arbeitsgruppe verfügbar sind. Daher wird eine optimale Anwendungsleistung gefördert, indem der Overhead des Thread-Erstellungs- und Beendigungsprozesses niedrig gehalten wird, was auf die Effizienz der Struktur zurückzuführen ist.

Bildbearbeitung

Bei intensiven Bildverarbeitungsaufgaben in Java-Programmen lohnt es sich, über die Implementierung des Objektpool-Entwurfsmusters nachzudenken. Durch die Nutzung bereits vorhandener Objekte aus einem dedizierten Pool können Sie die Leistung Ihrer Anwendung beschleunigen und gleichzeitig den gesamten Rechenbedarf Ihrer Fotobearbeitungsaufgaben reduzieren.

Dateisystemoperationen

Wenn Sie in Ihrer Java-Anwendung vor umfangreichen Bildverarbeitungsaufgaben stehen, lohnt es sich, über die Anwendung des Objektpool-Entwurfsmusters nachzudenken. Diese Technik nutzt vorhandene Elemente in einem bestimmten Pool, um die Ausgabegeschwindigkeit des Programms zu erhöhen und die für die Bearbeitung von Fotos erforderlichen Rechenressourcen zu reduzieren.

Fazit

Das Objektpool-Entwurfsmuster ist ein nützliches Entwurfsmuster in der Java-Programmierung, das sich für Situationen eignet, in denen die Kosten für die Erstellung neuer Objekte hoch sind. Es bietet eine Möglichkeit, die Versorgung mit wiederverwendbaren Objekten zu kontrollieren und so die Gesamtkosten für die Entwicklung neuer Produkte zu senken. Ein einfacher Objektpool oder ein generischer Objektpool sind zwei Beispiele für die Implementierung des Objektpool-Entwurfsmusters. Das Objektpool-Entwurfsmuster wird häufig in der Java-Programmierung verwendet, um teure Objekte wie Datenbankverbindungen und Netzwerkverbindungen zu verarbeiten. Es hat einen ähnlichen Zweck wie das Flyweight-Muster und das Singleton-Muster, hat jedoch unterschiedliche Verwendungszwecke.

Das obige ist der detaillierte Inhalt vonObjektpool-Entwurfsmuster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:tutorialspoint.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen