Запуск ExecutorService внутри запланированного метода

У меня есть вопрос о пулах потоков исполнителей, работающих один внутри другого.

Допустим, у меня есть служба Spring с запланированным методом, а другая служба создает ExecutorService и запускает некоторый метод действия.

@Service
public class ScheduledService
{

    @Autowired
    WorkService workService;

    @Scheduled(cron = "1 * * * * * ")
    public void method() {
        workService.execute();

    }
}

@Service
public class WorkService {

    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    public void execute() {
        executorService.submit(()->action());
    }

    private void action() {
        //some action
    }
}

Насколько я знаю, по умолчанию размер пула для @Scheduled равен 1. Внутри потока из этого пула я пытаюсь создать новый executorService с большим пулом.

Итак, вопрос в том, как выполнение будет распределяться по ядрам ЦП, действительно ли служба исполнителя будет работать параллельно? У меня ощущение, что нет. Я попытался запустить одно и то же задание на машине с 2 и 4 виртуальными ядрами, и время выполнения было одинаковым.

Спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
303
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, как он распределяется по ядрам ЦП, зависит также от того, насколько загружена операционная система, но, скажем, больше ничего не происходит, каждое ядро ​​ЦП может выполнять один поток. Если активных потоков больше, чем ядер ЦП, операционная система отвечает за распределение времени ЦП между потоками.

В вашем примере один поток выполнит метод @Scheduled, который довольно быстр, потому что он мало что делает, просто отправляет новое действие в службу-исполнитель.

Затем служба-исполнитель, имеющая до 20 потоков, выполнит действие в первом доступном потоке из 20.

Так что да, действия будут выполняться параллельно.

Вы можете попробовать очень часто планировать свой метод, скажем, каждую секунду:

@Scheduled(cron = "* * * ? * *")

Затем сделайте что-то дольше 1 секунды в своем действии (иначе действие завершится до следующего расписания). Вы увидите действия, выполняющие работу параллельно.

Кстати, почему бы не использовать ScheduledExecutorService? Или настроить Spring для использования нескольких потоков?

Спасибо! Да, я добавил журнал для распечатки имен потоков, он работает параллельно. Насчет ScheduledExecutorService — в реальном коде логика сложнее. Запланирована служба опроса очереди на наличие новых сообщений, если она получает сообщение - она ​​начинает обработку, и только в одной из частей обработки я могу делать вещи параллельно.

Danila Zharenkov 13.12.2020 14:13

Другие вопросы по теме