Core
35 уровень

ThreadPoolExecutor

Статья из группы Архив info.javarush
участников
Добрый день. ThreadPoolExecutor - 1Есть вопрос для собеседования такой. Сколько способов создания нитей вы знаете. В ответах фигурирует цифра 2: либо создать Thread, передав ему Runnable, либо создать объект класса-наследника Thread, в котором переопределён run(). Но я задумался: а два ли? Если использовать concurrent, например, Executors.newFixedThreadPool(5), то когда будут созданы объекты потоков, сразу при выполнении этого метода, или позже, когда появятся задачи для исполнения (ведь они могут и не появиться). Все эти методы-фабрики возвращают какие-то конфигурации ThreadPoolExecutor, у которого один из параметров конфигурации corePoolSize Про это поле написано: corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set С другой стороны, если задачи так и не поступили, то мы создали 5 workers в холостую, может они начинают создаваться, когда начинают поступать задачи? В общем 2 или 3 варианта всё таки можно иметь в виду в качестве варианта ответа на вопрос?
Комментарии (3)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Core
Уровень 35
7 марта 2017, 12:29
Спасибо за ответ. Executor то понятно, что ничего не создаёт, он интерфейс исполнения предлагает. Но речь ведь о ThreadPoolExecutor, даже из названия которого следует, что он влючает в себя пул потоков и реализацию исполнения (через цепочку наследования).

Я всегда считал, что концепция пула — это условно «создадим заранее и положим в одно место, чтобы потом от туда быстро брать», поэтому думал, что строркой
ExecutorService e = Executors.newFixedThreadPool(5)
мы заранее создаём пять объектов потоков. Полез в документацию, но перевёл не все нюансы, английский пока неидеален. Вот и спросил. Мне интересно знать, в какой момент создается объект потока: при исполнении строчки выше или при первом вызове execute/submit (а строка выше лишь указывает конфигурацию пула, но при этом не создает его).
Joysi
Уровень 41
7 марта 2017, 14:00
мы заранее создаём пять объектов потоков
Нет. Правильнее сказать, мы заранее настраиваем, что все в дальнейшем посылаемые в этот пул задачи будут параллельно исполняться максимум 5 одновременно.
Имея под рукой IDEA можно в режиме отладки просто узнать интересующую инфу на практике:

Попробуйте поэксперементируйте:
public static void main(String[] args) throws SQLException {
        ExecutorService es = Executors.newFixedThreadPool(5);
        System.out.println(es);
        ...




Или в разных точках, играя параметрами, например:
public static void main(String[] args) throws Exception {
        ExecutorService es = Executors.newFixedThreadPool(5);

        List<Callable<Integer>> tasks = new ArrayList<>();
        class CubusTask  implements Callable<Integer> {
            int num;
            CubusTask(int num) { this.num = num;}

            @Override
            public Integer call() throws Exception {
                return num*num*num;
            }
        }

        // Готовим пучок задач
        for(int j=0; j<10; j++) tasks.add(new CubusTask(j));
        // Запускаем их
        List<Future<Integer>> listResult = es.invokeAll(tasks);

        // Ждем завершения
        if (!es.awaitTermination(5, TimeUnit.SECONDS))
            es.shutdownNow();

        // Печатаем подсчитанные результаты
        for(int i=0; i<tasks.size(); i++)
            System.out.println("Cube of " + i + " is " + listResult.get(i).get());

    }
Joysi
Уровень 41
7 марта 2017, 10:52
Наверное, ответ имеется в виду без знания Concurrent-ов. Если вы дополнительно расскажете про них, то Вам на собеседовании будут дополнительные плюсы. Ну и экзекутор он вроде не создает нити, он супервайзит их выполнение. А создавать задачи в Concurrent-е можно многими способами, например реализовав интерфейс Task (его метод Call), ну и далее создав Listи запустить их в дальнейшем через executor.invokeAll();