Maison  >  Article  >  Java  >  Modèle de conception de pool d’objets

Modèle de conception de pool d’objets

WBOY
WBOYavant
2023-08-19 16:29:21546parcourir

Modèle de conception de pool d’objets

Un modèle de conception de logiciel souvent utilisé dans la programmation Java est le modèle de conception de pool d'objets. Ce mode contrôle la manière dont les objets du pool d'objets sont créés et détruits.

Utilisez le modèle de conception du pool d'objets pour gérer la production et la destruction d'objets. Le concept de ce modèle est d’accumuler des objets réutilisables au lieu d’en créer de nouveaux à chaque fois qu’ils sont nécessaires. Pour les situations où le coût de production de nouveaux objets est important, comme les connexions réseau, les connexions de bases de données ou les objets coûteux, les programmeurs Java utilisent souvent le modèle de conception de pool d'objets.

Syntaxe de conception de pool d'objets

En Java, la syntaxe du modèle de conception du pool d'objets est la suivante −

  • Créez une collection d'objets de taille fixe.

  • Initialisez les éléments de la piscine.

  • Suivez les éléments actuellement dans la piscine.

  • Chaque fois que nécessaire, vérifiez s'il y a un objet accessible dans la piscine.

  • Veuillez vous assurer de récupérer vous-même rapidement tous les objets disponibles dans la piscine et de les restituer de manière appropriée si nécessaire

  • Cependant, s'il n'y a actuellement aucun article disponible dans ce dépôt, nous demandons qu'un nouvel article soit créé immédiatement pour éviter de perdre du temps ou des ressources puis remis en circulation.

Différents algorithmes pour la conception de pools d'objets

Le modèle de conception de pool d'objets Java peut être utilisé pour divers algorithmes. Voici trois stratégies possibles, chacune avec des implémentations de code uniques :

Initialisation et synchronisation paresseuses

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

La technique utilisée ici met l'accent sur la sécurité des threads grâce à l'initialisation d'un pool d'objets par conséquent paresseux et synchronisé avec des limitations de capacité prédéfinies qui peuvent être modifiées en cas d'expansion. Les pools vides permettent une production sûre de nouvelles instances, tandis que les instances non complètes sont soigneusement réintroduites pour maintenir une intégrité opérationnelle appropriée. .

Initialisation impatiente à l'aide de structures de données concurrentes

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

Dans cette implémentation, une variable d'instance finale statique est utilisée pour initialiser avec impatience le pool d'objets. La structure de données sous-jacente est une LinkedBlockingQueue, qui assure la sécurité des threads sans avoir besoin de synchronisation. Lors de l'initialisation, les objets sont ajoutés au pool et take() est utilisé pour les récupérer de la file d'attente en cas de besoin. Lorsqu'un élément est publié, utilisez offer() pour le remettre en file d'attente.

Expiration basée sur le temps

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

}

Le pool d'objets de cette version utilise un mécanisme d'expiration basé sur le temps au lieu d'une taille fixe. Lorsqu'un objet est nécessaire, la fonction poll() est utilisée pour supprimer l'objet du pool. Lorsqu'il n'y a pas d'objet disponible, la fonction attendra un certain temps puis retournera null. Les objets sont générés à la demande. Si aucun objet n'existe, un nouvel objet sera généré et renvoyé. Lorsqu'un objet est libéré, utilisez offer() pour le remettre dans le pool. La fonction expireObjects() est utilisée pour supprimer les éléments expirés du pool en fonction de la valeur de délai d'attente fournie.

Différentes façons d'utiliser le modèle de conception Object Pool

Le modèle de conception de pool d’objets Java peut être implémenté de plusieurs manières. Vous trouverez ci-dessous deux méthodes typiques, y compris des exemples de code et des résultats −

Méthode 1 : Modèle de conception de pool d'objets simple

Une façon de créer un pool d'objets simple et pratique consiste à adopter une approche basée sur des tableaux. Cette approche fonctionne comme suit : une fois entièrement générés, tous les objets sont inclus dans le tableau "pool" correspondant pour une utilisation ultérieure au moment de l'exécution, la collection est vérifiée pour déterminer si l'un des éléments requis est disponible ; S'il peut être obtenu à partir de l'inventaire existant, il sera restitué immédiatement ; sinon, un autre nouvel objet sera généré en fonction de la demande.

Exemple

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

Exemple

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

Sortie

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

Méthode 2 : Modèle de conception de pool d'objets universel

En utilisant des listes comme base, cette technique facilite la création d'un pool d'objets standard, en stockant les objets dans la collection jusqu'à ce qu'ils soient entièrement générés et inclus dans la collection. Chaque fois que l'accès à un élément est requis, le système parcourt les options disponibles dans le pool. S'il y a une option disponible, cela suffit ; mais si aucune n'est disponible, vous devez créer un autre nouveau projet.

Exemple

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

Sortie

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

Bonnes pratiques d'utilisation des verrous au niveau de la classe

Les programmeurs Java utilisent souvent le modèle de conception de pool d'objets lorsque le coût de production de nouveaux objets est élevé. Les scénarios d'utilisation typiques incluent −

Connexion Internet

Dans un programme Java, les connexions réseau peuvent être gérées à l'aide du modèle de conception de pool d'objets. Il est préférable de réutiliser les connexions existantes d'un pool plutôt que de devoir en créer de nouvelles à chaque fois que cela est nécessaire. Cela peut améliorer les fonctionnalités de l'application tout en allégeant l'environnement. charge sur le serveur réseau.

Connexion à la base de données

Semblable à la gestion des connexions réseau, les applications Java peuvent également utiliser le modèle de conception de pool d'objets pour gérer les connexions de base de données. Il est préférable de réutiliser une connexion existante du pool plutôt que d'en créer une nouvelle à chaque fois qu'une connexion à la base de données est nécessaire. Cela peut améliorer les performances des applications et réduire la charge sur le serveur de base de données.

Bassin de discussions

Les développeurs utilisant des programmes Java doivent adopter le modèle de conception du pool d'objets pour gérer efficacement les pools de threads. Plutôt que de recréer chaque thread requis selon les besoins, une utilisation bien planifiée repose sur la réutilisation des threads préexistants disponibles dans un groupe de travail désigné. Par conséquent, il encourage des performances optimales des applications en maintenant à un faible niveau la surcharge du processus de création et de terminaison des threads, pilotée par l’efficacité de la structure.

Traitement d'image

Lorsque vous traitez des tâches intensives de traitement d'images dans des programmes Java, il vaut la peine d'envisager d'implémenter le modèle de conception de pool d'objets. En exploitant les objets préexistants d'un pool dédié, vous pouvez accélérer les performances de votre application tout en réduisant les exigences informatiques globales de vos tâches de retouche photo.

Opérations du système de fichiers

Si vous êtes confronté à des tâches lourdes de traitement d'image dans votre application Java, il vaut la peine d'envisager d'appliquer le modèle de conception de pool d'objets. Cette technique utilise les éléments existants dans un pool spécifique pour augmenter la vitesse de sortie du programme et réduire les ressources informatiques requises pour éditer des photos.

Conclusion

Le modèle de conception de pool d'objets est un modèle de conception utile dans la programmation Java, adapté aux situations où le coût de création de nouveaux objets est élevé. Il permet de contrôler l’offre d’objets réutilisables, réduisant ainsi le coût global de création de nouveaux produits. Le pool d'objets simple ou le pool d'objets génériques sont deux exemples d'implémentation du modèle de conception de pool d'objets. Le modèle de conception de pool d'objets est souvent utilisé dans la programmation Java pour gérer des objets coûteux, tels que les connexions de base de données et les connexions réseau. Son objectif est similaire au modèle Flyweight et au modèle Singleton, mais a des utilisations différentes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer