Question

Le titre de cette question me fait douter de son existence, mais néanmoins:

Je voudrais savoir s'il existe une implémentation de Java BlockingQueue , qui est limité par la taille et qui ne bloque jamais, mais lève une exception lorsque vous essayez de mettre en file d'attente trop d'éléments.

Modifier : je passe la BlockingQueue à un exécuteur, qui, je suppose, utilise sa méthode add () et non pas offer (). On peut écrire une BlockingQueue qui englobe une autre BlockingQueue et déléguer les appels à add () to offer ().

Était-ce utile?

La solution

Modifier: Sur la base de votre nouvelle description, je pense que vous posez la mauvaise question. Si vous utilisez un exécuteur, vous devez probablement définir un paramètre personnalisé RejectedExecutionHandler plutôt que de modifier la file d'attente. Cela ne fonctionne que si vous utilisez un ThreadPoolExecutor, mais si vous ne l'êtes pas, il serait probablement préférable de modifier l'Executor plutôt que la file d'attente.

J’estime que c’est une erreur de surcharger une offre et de la faire se comporter comme une addition. Les méthodes d'interface constituent un contrat. Le code client qui utilise des files d'attente de blocage dépend des méthodes qui respectent les spécifications de la documentation. Briser cette règle ouvre la voie à un monde de blessures. Ça, et c'est inélégant.

Le add La méthode () sur BlockingQueues fait cela, mais ils ont aussi une offer () est généralement le meilleur choix. Dans la documentation de l'offre ():

  

Insère l'élément spécifié à la   queue de cette file d'attente s'il est possible   de le faire immédiatement sans dépasser   la capacité de la file d'attente, retournant vrai   en cas de succès et faux si cette file d'attente   est rempli. Cette méthode est généralement   préférable à la méthode add (E), qui peut   ne pas insérer un élément que par   lancer une exception.

Cela fonctionne pour toutes ces files d'attente, quelle que soit leur implémentation (ArrayBlockingQueue, LinkedBlockingQueue, etc.)

BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
System.out.println(q.offer("foo")); // true
System.out.println(q.offer("bar")); // true
System.out.println(q.offer("baz")); // false

Autres conseils

  

On peut écrire une BlockingQueue qui   encapsule une autre BlockingQueue et   délègue des appels à add () to offer ().

Si cela est censé être une question ... la réponse est "Oui", mais vous pouvez le faire plus proprement en créant une sous-classe qui remplace la méthode add (). Le seul problème (dans les deux cas) est que votre version de add ne peut pas émettre d'exceptions vérifiées qui ne figurent pas dans la méthode que vous substituez. Par conséquent, votre "bloc" & bloc; l'exception devra être décochée.

c'est dommage, vous ne pouvez pas bloquer, il y a tellement de cas d'utilisation que vous voudriez bloquer, l'idée même de fournir votre propre file d'attente de blocage limitée à l'exécuteur n'a aucun sens.

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
            if (runState == RUNNING && workQueue.***offer***(command)) {
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }
            else if (!addIfUnderMaximumPoolSize(command))
                reject(command); // is shutdown or saturated
        }
    }

Un cas d'utilisation simple permettant d'exécuter des requêtes de la base de données source en batch (exécuteur), de les enrichir en batch et de les placer dans une autre base de données (exécuteur). Vous souhaitez exécuter les requêtes uniquement aussi rapidement qu'elles sont insérées dans une autre base de données. Dans ce cas, l'exécutant dest doit accepter un exécutant lié bloquant pour résoudre le problème plutôt que de continuer à interroger et de vérifier le nombre de requêtes terminées pour exécuter davantage de requêtes.

oups plus, voir mon dernier commentaire:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top