Article de reference

Modèle de pool d'objets

C++ En C++26 , la bibliothèque standard C++ introduit un nouvel en-tête <hive> contenant la structure de données `List<List<Object>` std::hive , qui implémente essentiellement u...

C++

En C++26 , la bibliothèque standard C++ introduit un nouvel en-tête <hive>contenant la structure de données `List<List<Object>` std::hive, qui implémente essentiellement un pool d'objets. Il s'agit d'une collection qui réutilise la mémoire des éléments effacés. Elle inclut également une classe std::hive_limitsfournissant des informations de disposition sur les limites de capacité des blocs. std::hive est basée sur la classe plf::colonyde la plfbibliothèque.

import std ;using std :: hive ; using std :: string ;int main () { hive < string > stringHive ;// Insérer stringHive.insert ( " foo" ) ; stringHive.insert ( " bar" ) ;// Supprimer std :: erase ( stringHive , string ( "foo" ));// Itération pour ( const auto & valeur : stringHive ) { std :: println ( "{}" , valeur ); }retourner 0 ; }

C#

Dans la bibliothèque de classes de base .NET , certains objets implémentent ce modèle. System.Threading.ThreadPoolest configuré pour allouer un nombre prédéfini de threads. Une fois libérés, ces threads sont disponibles pour un autre calcul. Ainsi, il est possible d'utiliser des threads sans supporter le coût de leur création et de leur libération.

Le code suivant illustre l'implémentation en C# du patron de conception de pool d'objets. Le pool est représenté par une classe statique, car il est rare d'avoir besoin de plusieurs pools. Cependant, l'utilisation de classes d'instance est tout aussi acceptable.

espace de noms Wikipedia.Exemples ;using System ; using System.Collections.Generic ;// La classe PooledObject est le type coûteux ou lent à instancier, // ou dont la disponibilité est limitée, et qui doit donc être conservé dans le pool d'objets. public class PooledObject { private DateTime _createdAt = DateTime . Now ;public DateTime CreatedAt => _createdAt ;public string TempData { get ; set ; } }// La classe Pool contrôle l'accès aux objets mis en pool. Elle maintient une liste des objets disponibles et une // collection des objets obtenus du pool et en cours d'utilisation. Le pool garantit que les objets libérés // sont retournés dans un état approprié, prêts à être réutilisés. public static class Pool { private static List < PooledObject > _available = new (); private static List < PooledObject > _inUse = new ();public static PooledObject GetObject ( ) { lock ( _available ) { if ( _available.Count ! = 0 ) { PooledObject po = _available [ 0 ] ; _inUse.Add ( po ) ; _available.RemoveAt ( 0 ) ; return po ; } else { PooledObject po = new ( ) ; _inUse.Add ( po ) ; return po ; } } }public static void ReleaseObject ( PooledObject po ) { CleanUp ( po );verrouiller ( _disponible ) { _disponible . Ajouter ( po ); _enUtilisation . Supprimer ( po ); } }private static void CleanUp ( PooledObject po ) { po . TempData = null ; } }

Dans le code ci-dessus, l'objet PooledObject possède des propriétés relatives à sa date de création, ainsi qu'une autre, modifiable par le client, qui est réinitialisée lorsque l'objet PooledObject est remis dans le pool. Le code illustre le processus de nettoyage lors de la libération d'un objet, garantissant ainsi son état valide avant qu'il puisse être de nouveau demandé au pool.

Aller

Le code Go suivant initialise un pool de ressources d'une taille spécifiée (initialisation concurrente) pour éviter les problèmes de concurrence de ressources via les canaux, et dans le cas d'un pool vide, configure le traitement du délai d'attente pour empêcher les clients d'attendre trop longtemps.

// pool de packages pool de packagesimport ( "erreurs" "log" "math/rand" "sync" "time" )const getResMaxTime = 3 * time.Secondvar ( ErrPoolNotExist = errors . New ( "pool not exist" ) ErrGetResTimeout = errors . New ( "get resource time out" ) )// Type de ressource Resource struct { resId int }// NewResource Simule la création d'une ressource initiale lente // (par exemple, la connexion TCP, l'acquisition d'une clé symétrique SSL et l'authentification prennent du temps) func NewResource ( id int ) * Resource { time . Sleep ( 500 * time . Millisecond ) return & Resource { resId : id } }// Les ressources de simulation consomment du temps et leur consommation aléatoire est de 0 à 400 ms. func ( r * Resource ) Do ( workId int ) { time . Sleep ( time . Duration ( rand . Intn ( 5 )) * 100 * time . Millisecond ) log . Printf ( "Utilisation de la ressource n° %d, tâche terminée %d " , r . resId , workId ) }// Pool basé sur l'implémentation de canaux Go, pour éviter les problèmes d'état de concurrence des ressources. Type Pool chan * Ressource// Créer un pool de ressources de la taille spécifiée // Les ressources sont créées simultanément pour gagner du temps d'initialisation func New ( size int ) Pool { p : = make ( Pool , size ) wg := new ( sync.WaitGroup ) wg.Add ( size ) for i := 0 ; i < size ; i ++ { go func ( resId int ) { p < - NewResource ( resId ) wg.Done ( ) } ( i ) } wg.Wait ( ) return p }// GetResource basé sur le canal, l'état de concurrence des ressources est évité et un délai d'acquisition de ressource est défini pour un pool vide func ( p Pool ) GetResource () ( r * Resource , err error ) { select { case r := <- p : return r , nil case <- time . After ( getResMaxTime ): return nil , ErrGetResTimeout } }// GiveBackResource renvoie des ressources au pool de ressources func ( p Pool ) GiveBackResource ( r * Resource ) error { if p == nil { return ErrPoolNotExist } p <- r return nil }// paquet principal paquet principalimport ( "github.com/tkstorm/go-design/creational/object-pool/pool" "log" "sync" )func main () { // Initialiser un pool de cinq ressources, // qui peut être ajusté à 1 ou 10 pour observer la différence size : = 5 p : = pool.New ( size )// Invoque une ressource pour effectuer la tâche id doWork := func ( workId int , wg * sync . WaitGroup ) { defer wg . Done () // Récupère la ressource du pool de ressources res , err := p . GetResource () if err != nil { log . Println ( err ) return } // Ressources à retourner defer p . GiveBackResource ( res ) // Utilise les ressources pour traiter la tâche res . Do ( workId ) }// Simuler 100 processus concurrents pour obtenir des ressources du pool d'actifs num := 100 wg := new ( sync . WaitGroup ) wg . Add ( num ) for i := 0 ; i < num ; i ++ { go doWork ( i , wg ) } wg . Wait () }

Java

Java prend en charge le pooling de threads via java.util.concurrent.ExecutorServicedes classes associées. Le service d'exécution dispose d'un certain nombre de threads « de base » qui ne sont jamais supprimés. Si tous les threads sont occupés, le service alloue le nombre autorisé de threads supplémentaires, qui seront supprimés s'ils ne sont pas utilisés pendant une durée déterminée. Si le nombre de threads disponibles est insuffisant, les tâches peuvent être placées dans une file d'attente. Enfin, si cette file d'attente risque de devenir trop longue, il est possible de configurer le service pour suspendre le thread demandeur.

Dans PooledObject.java :

paquet org.wikipedia.examples ;public class PooledObject { private String temp1 ; private String temp2 ; private String temp3 ; public String getTemp1 () { return temp1 ; }public void setTemp1 ( String temp1 ) { this . temp1 = temp1 ; }public String getTemp2 () { return temp2 ; }public void setTemp2 ( String temp2 ) { this . temp2 = temp2 ; }public String getTemp3 () { return temp3 ; }public void setTemp3 ( String temp3 ) { this . temp3 = temp3 ; } }

Dans PooledObjectPool.java :

paquet org.wikipedia.examples ;import java.util.HashMap ; import java.util.Map ;public class PooledObjectPool { public static final long EXPIRY_TIME = 6000 ; // 6 secondesprivate static Map < PooledObject , Long > available = new HashMap <> (); private static Map < PooledObject , Long > inUse = new HashMap <> (); public synchronized static PooledObject getObject ( ) { long now = System.currentTimeMillis ( ); if ( ! available.isEmpty ( )) { for ( Map.Entry < PooledObject , Long > entry : available.entrySet ()) { if ( now - entry.getValue ( ) > EXPIRY_TIME ) { // l' objet a expiré popElement ( available ); } else { PooledObject po = popElement ( available , entry.getKey ( ) ) ; push ( inUse , po , now ) ; return po ; } } }// Soit aucun PooledObject n'est disponible, soit ils ont tous expiré ; il faut donc en créer un nouveau. return createPooledObject ( now ); } private synchronized static PooledObject createPooledObject ( long now ) { PooledObject po = new PooledObject (); push ( inUse , po , now ); return po ; }private synchronized static void push ( HashMap < PooledObject , Long > map , PooledObject po , long now ) { map.put ( po , now ) ; }public static void releaseObject ( PooledObject po ) { cleanUp ( po ) ; available.put ( po , System.currentTimeMillis ( )); inUse.remove ( po ) ; } private static PooledObject popElement ( HashMap < PooledObject , Long > map ) { Map.Entry < PooledObject , Long > entry = map.entrySet ( ) . iterator ( ) . next ( ) ; PooledObject key = entry.getKey ( ) ; // Long value = entry.getValue( ) ; map.remove ( entry.getKey ( ) ) ; return key ; } private static PooledObject popElement ( HashMap < PooledObject , Long > map , PooledObject key ) { map.remove ( key ) ; return key ; } public static void cleanUp ( PooledObject po ) { po.setTemp1 ( null ) ; po.setTemp2 ( null ) ; po.setTemp3 ( null ) ; } }

Rouiller

Il existe une crate Rust appelée colony qui est basée sur std::hive(ou plf::colony) de C++. Elle n'est plus maintenue depuis janvier 2024.

utiliser colonie :: Colonie ;fn main () { let mut colonie : Colonie = Colonie :: nouvelle ();// Insérer let foo_handle = colony.insert ( " foo" ); let bar_handle = colony.insert ( " bar" ) ;// Supprimer assert_eq! ( colony . remove ( foo_handle ), Some ( "foo" ));// Lookup assert_eq! ( colony . get ( foo_handle ), None ); assert_eq! ( colony . get ( bar_handle ), Some ( & "bar" ));// Itération pour ( clé , & valeur ) dans colonie . iter () { assert_eq! (( clé , valeur ), ( bar_handle , "bar" )); } }

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index