У меня есть эта проблема, я имею
private ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
и задача, которая создается каждые 50 миллисекунд:
executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS);
myTask
иногда требуйте времени к полному (как приблизительно 2-3 секунды), но newSingleThreadScheduledExecutor гарантирует, что затем запланировал myTask, будет ожидать, пока текущий не завершается.
Однако я время от времени получаю эту ошибку:
выполнитесь: java.util.concurrent.RejectedExecutionException
Что мне делать? Спасибо
Подумайте, что делает исполнитель. Он выполняет одну задачу каждые 50 миллисекунд в соответствии с вашими инструкциями. Если предположить, что выполнение этой задачи занимает менее 50 миллисекунд, тогда все в порядке. Однако время от времени для запуска требуется 2-3 секунды. Когда это происходит, исполнитель по-прежнему пытается выполнить каждые 50 миллисекунд, но, поскольку он имеет только один поток, он не может и отклоняет те выполнения, которые запускаются, пока ваша длительная задача все еще выполняется. Это вызывает исключение, которое вы видите.
У вас есть два варианта исправить это (при условии, что вы хотите придерживаться одного потока):
Используйте scheduleWithFixedDelay
вместо scheduleAtFixedRate
. Если вы внимательно прочитаете javadoc, вы Вы увидите, что scheduleWithFixedDelay
будет ждать 50 миллисекунд между завершением одной задачи и началом следующей, поэтому она никогда не будет "перекрываться", даже если одна из них занимает много времени. Напротив, scheduleAtFixedRate
будет пытаться выполнить каждые 50 миллисекунд, независимо от того, сколько времени занимает каждое из них.
Измените способ, которым исполнитель обрабатывает сбои для выполнения. По умолчанию исключение регистрируется, но вы можете указать ему, например, игнорировать его. Взгляните на подклассы java.util.concurrent.RejectedExecutionHandler
, например DiscardPolicy
, который просто незаметно отбрасывает задачу, которая не может быть запущена. Вы можете использовать их, напрямую создав ScheduledThreadPoolExecutor
и передав обработчик в конструктор,
Это исключение будет сгенерировано, когда:
Я предполагаю, что последнее это происходит. Когда вы выполняете свою задачу, и это занимает много времени, последующие запланированные задачи не могут быть запущены, поскольку в пуле недостаточно потоков.
Либо:
См. Также ThreadPoolExecutor javadoc