Почему ThreadPoolExecutor уменьшает потоки ниже размера corePoolSize после keepAliveTime?

Я возился с различными стратегиями объединения потоков с помощью ThreadPoolExecutor с JDK6. У меня работает приоритетная очередь, но я не был уверен, нравится ли мне то, как размер пула не увеличивается после keepAliveTime (что вы получаете с неограниченной очередью). Итак, я смотрю на ThreadPoolExecutor, используя LinkedBlockingQueue и политику CallerRuns.

Проблема, с которой я столкнулся сейчас, заключается в том, что пул увеличивается, как поясняется в документации, но после того, как задачи завершены и в игру вступает keepAliveTime, getPoolSize показывает, что пул уменьшается до нуля. Приведенный ниже пример кода должен позволить вам увидеть основу для моего вопроса:

public class ThreadPoolingDemo {
    private final static Logger LOGGER =
         Logger.getLogger(ThreadPoolingDemo.class.getName());

    public static void main(String[] args) throws Exception {
        LOGGER.info("MAIN THREAD:starting");
        runCallerTestPlain();   
    }

    private static void runCallerTestPlain() throws InterruptedException {
        //10 core threads, 
        //50 max pool size, 
        //100 tasks in queue, 
        //at max pool and full queue - caller runs task
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(10, 50,
            5L, TimeUnit.SECONDS, new LinkedBlockingQueue(100),
            new ThreadPoolExecutor.CallerRunsPolicy());

        //dump 5000 tasks on the queue
        for (int i = 0; i < 5000; i++) {
            tpe.submit(new Runnable() {
                @Override
                public void run() {
                    //just to eat some time and give a little feedback
                    for (int j = 0; j < 20; j++) {
                        LOGGER.info("First-batch Task, looping:" + j + "["
                               + Thread.currentThread().getId() + "]");
                    }
                }
            }, null);
        }
        LOGGER.info("MAIN THREAD:!!Done queueing!!");

        //check tpe statistics forever
        while (true) {
            LOGGER.info("Active count: " + tpe.getActiveCount() + " Pool size: "
                 + tpe.getPoolSize() + " Largest Pool: " + tpe.getLargestPoolSize());
            Thread.sleep(1000);
        }
    }
}

Я нашел старую ошибку, которая, похоже, связана с этой проблемой, но она была закрыта: http://bugs.sun.com/bugdatabase/view_bug. сделать?bug_id=6458662. Может ли это все еще присутствовать в 1.6 или я что-то упустил?

Похоже, я уклонился от этого (http://www.codinghorror.com/blog/2012/03/rubber-duck-problem-solving.html). Ошибка, о которой я упоминал выше, связана с этой: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6576792, где проблема, кажется, решена в 1.7 (я загрузил 1.7 и проверено - исправлено...). Думаю, моя главная проблема заключалась в том, что эта фундаментальная ошибка сохранялась почти десятилетие.Я потратил слишком много времени на написание этого, чтобы не опубликовать его сейчас, надеюсь, что это кому-то поможет.

9
задан Gray 6 October 2013 в 05:01
поделиться