9
votes

Est-ce que cette piscine d'objet Java de base fonctionne-t-elle?

Le piscine d'objet de base suivant fonctionne-t-il? J'ai un plus sophistiqué basé sur la même idée (c'est-à-dire le maintien d'un sémaphore et un blocageQueue). Ma question est - ai-je besoin de sémaphore et de blocageQueue? Ai-je raison que je n'ai pas besoin de faire de la synchronisation?

import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;

public final class Pool<T> {

    private final BlockingQueue<T> objects;
    private final Semaphore permits;

    public Pool(Collection<? extends T> objects) {
        // we have as many permits as objects in our pool:
        this.permits = new Semaphore(objects.size());
        this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
    }

    public T borrow() {
        this.permits.acquireUninterruptibly();
        // we have a permit, so there must be one in there:
        return this.objects.poll();
    }

    public void giveBack(T object) {
        this.objects.add(object);
        this.permits.release();
    }
}


3 commentaires

Toute raison que vous faites cela vous-même? Apache Commons Pool le fait hors de l'étagère.


Qu'est-ce que Apachecommonspool fournit un blocageQueue ne le fait pas? Il tire dans une grande bibliothèque pour définir un grand ensemble d'interfaces "standard" lorsqu'un java.Util.concurrent.BlockingQueue prend déjà en charge toutes les opérations définies.


@skaffman Pouvez-vous aider Stackoverflow.com/questions/43860936/...


7 Réponses :


0
votes

Peut-être que vous devriez vérifier que les objets existent, c'est la seule chose que j'ai.

Edit: Je n'ai pas lu le code soigneusement. J'ai donc écrit un peu le poteau. : (


0 commentaires

2
votes

Utilisation prise () au lieu de sondage () et mettre () au lieu d'ajouter (). Le sémaphore est alors complètement redondant pour que vous puissiez simplement vous en débarrasser. Mais oui, ça a l'air bien.


0 commentaires

16
votes

Comme il a été souligné, un blocage lié seul serait suffisant. Par exemple, le code suivant fera ce que vous voulez:

import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public final class Pool<T> {

    private final BlockingQueue<T> objects;

    public Pool(Collection<? extends T> objects) {
        this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
    }

    public T borrow() throws InterruptedException {
        return this.objects.take();
    }

    public void giveBack(T object) throws InterruptedException {
        this.objects.put(object);
    }
}


2 commentaires

Exemple sympa et propre - mais mon choix serait de rendre la classe de piscine abstrait plutôt que de finale, et d'ajouter une méthode abstraite "T CreateExPlivenClockObject ()".


Je viens de réaliser que ma suggestion ne fonctionnerait pas comme votre solution initialise statiquement la mémoire tampon à l'intérieur du constructeur. Essayera de modifier votre exemple pour que la capacité à créer des objets coûteux à la demande.



2
votes

Cela ne vaut rien que d'une arrayblockingQueue crée un objet lorsque vous en apportez une entrée. Donc, votre piscine ne sauvegardera donc pas d'objets. Il ne pouvait que vous aider si vos objets sont chers à créer.


0 commentaires

6
votes

Un exemple de Sjlee quelque peu modifié; permettant la création d'objets coûteux à la demande. Mon cas n'a pas besoin d'une installation de blocage d'où je l'ai remplacé avec un type de file d'attente non bloquante. En tant que prestation, il n'est pas nécessaire de faire face à une interruptionExceptions. XXX


2 commentaires

Ce n'est pas idéal. Vous allez créer autant d'objets coûteux que jamais nécessaires simultanément afin que votre file d'attente a à peu près une croissance sans bornes. Le point d'une piscine est qu'il a une taille maximale.


On dirait que vous avez manqué l'élément clé en question Titre: Basic . Nous ne conçons pas la solution pleine épouse ici; Parfois, Basic couvre tous les besoins.



3
votes

peut-être utiliser une pile au lieu d'une file d'attente? Cela donne une chance d'obtenir un objet qui reste assis dans le cache du processeur.


0 commentaires

0
votes

Voici une piscine plus simple et complète pour ce dernier. C'est mieux que le plus simple, et c'est simple.

de Ici p>

/**
 * 
 * @see <a href=http://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html>simple pool</>
 */
abstract static class ObjectPool<T>
{
    private ConcurrentLinkedQueue<T> pool;

    private ScheduledExecutorService executorService;

    /**
     * Creates the pool.
     *
     * @param minIdle minimum number of objects residing in the pool
     */
    public ObjectPool(final int minIdle)
    {
        // initialize pool
        initialize(minIdle);
    }

    /**
     * Creates the pool.
     *
     * @param minIdle            minimum number of objects residing in the pool
     * @param maxIdle            maximum number of objects residing in the pool
     * @param validationInterval time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread.
     *                           When the number of objects is less than minIdle, missing instances will be created.
     *                           When the number of objects is greater than maxIdle, too many instances will be removed.
     */
    public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval)
    {
        // initialize pool
        initialize(minIdle);

        // check pool conditions in a separate thread
        executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleWithFixedDelay(new Runnable()
        {
            @Override
            public void run()
            {
                int size = pool.size();
                if (size < minIdle)
                {
                    int sizeToBeAdded = minIdle - size;
                    for (int i = 0; i < sizeToBeAdded; i++)
                    {
                        pool.add(createObject());
                    }
                } else if (size > maxIdle)
                {
                    int sizeToBeRemoved = size - maxIdle;
                    for (int i = 0; i < sizeToBeRemoved; i++)
                    {
                        pool.poll();
                    }
                }
            }
        }, validationInterval, validationInterval, TimeUnit.SECONDS);
    }

    /**
     * Gets the next free object from the pool. If the pool doesn't contain any objects,
     * a new object will be created and given to the caller of this method back.
     *
     * @return T borrowed object
     */
    public T borrowObject()
    {
        T object;
        if ((object = pool.poll()) == null)
        {
            object = createObject();
        }

        return object;
    }

    /**
     * Returns object back to the pool.
     *
     * @param object object to be returned
     */
    public void returnObject(T object)
    {
        if (object == null)
        {
            return;
        }

        this.pool.offer(object);
    }

    /**
     * Shutdown this pool.
     */
    public void shutdown()
    {
        if (executorService != null)
        {
            executorService.shutdown();
        }
    }

    /**
     * Creates a new object.
     *
     * @return T new object
     */
    protected abstract T createObject();

    private void initialize(final int minIdle)
    {
        pool = new ConcurrentLinkedQueue<T>();

        for (int i = 0; i < minIdle; i++)
        {
            pool.add(createObject());
        }
    }
}


0 commentaires