La création d'une dynamique (croissance/réduire) le pool de thread

J'ai besoin de mettre en œuvre un pool de threads en Java (java.util.simultanées), dont le nombre de threads est à une certaine valeur minimale lorsqu'il est inactif, pousse jusqu'à une limite supérieure (mais jamais plus) lorsque les travaux sont soumis en plus rapidement qu'ils ne le fini de l'exécution, et se rétrécit en arrière de la limite inférieure quand tous les travaux sont effectués et non plus de travaux sont soumis.

Comment voulez-vous mettre en place quelque chose comme ça? J'imagine que ce serait un assez commune scénario d'utilisation, mais apparemment le java.util.concurrent.Executors usine méthodes ne peuvent créer de taille fixe, de piscines et de bassins que croître indéfiniment lorsque de nombreux travaux sont soumis. Le ThreadPoolExecutor classe fournit corePoolSize et maximumPoolSize paramètres, mais sa documentation semble impliquer que la seule façon de jamais avoir plus de corePoolSize threads en même temps est d'utiliser un délimitée de la file d'attente de travail, auquel cas, si vous avez atteint maximumPoolSize threads, vous obtiendrez les rejets qui vous avez à traiter avec vous-même? Je suis venu avec cette:

//pool creation
ExecutorService pool = new ThreadPoolExecutor(minSize, maxSize, 500, TimeUnit.MILLISECONDS,
    new ArrayBlockingQueue<Runnable>(minSize));
...

//submitting jobs
for (Runnable job : ...) {
    while (true) {
        try {
            pool.submit(job);
            System.out.println("Job " + job + ": submitted");
            break;
        } catch (RejectedExecutionException e) {
            //maxSize jobs executing concurrently atm.; re-submit new job after short wait
            System.out.println("Job " + job + ": rejected...");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e1) {
            }
        }
    }
}

Suis-je surplombant quelque chose? Est-il une meilleure façon de le faire? Aussi, selon les besoins, il peut être contestable que le code ci-dessus ne seront pas finir au moins jusqu'à (je pense) (total number of jobs) - maxSize emplois ont fini. Donc, si vous voulez être en mesure de présenter un nombre arbitraire d'emplois dans la piscine et de procéder immédiatement, sans attendre que l'un d'eux pour finir, je ne vois pas comment vous pourriez le faire sans avoir un "emploi sumitting" thread qui gère le nécessaire de la surabondance de la file d'attente pour contenir les emplois. AFAICS, si vous utilisez une surabondance de la file d'attente pour le ThreadPoolExecutor lui-même, son nombre de thread ne sera jamais pousser au-delà de corePoolSize.

Je dois admettre, je ne vois pas l'utilité de la dynamique d'une taille de pool de threads. Est-ce que votre nombre de processeurs sur votre conseil de le modifier au cours de la disponibilité de votre application?
Pourquoi est - newCachedThreadPool ne convient pas à votre situation? Automatiquement, il tue les threads qui ne sont plus utilisés.
Ce qui serait si votre threads inactifs n'est pas mort? Disons que vous avez eu une taille fixe de la piscine de la taille maximale de tous les temps? Qu'arriverait-il?
AFAICS, newCachedThreadPool crée un pool dont le nombre de threads peut croître sans limites si vous envoyez de nombreux travaux en cours d'exécution.
Non, le nombre de processeurs ne changera pas lors de l'exécution, mais je ne vois pas en quoi c'est pertinent si les travaux sont largement dépendant des e/S plutôt qu'en CPU. Dans ce cas, vous permettent d'augmenter le débit par l'utilisation de plusieurs threads, même sur un système monoprocesseur.

OriginalL'auteur Olaf Klischat | 2012-06-28