Вопрос затрагивает сложную тему. В качестве первого комментария я хотел бы подчеркнуть, что при работе с ExecutorService
вы, вероятно, должны придерживаться кодирования для интерфейсов, а не для реализации. Это должно избежать некоторой сложности того, что вы пытаетесь сделать.
В данном случае вы указываете использование метода remove(), который является общедоступным, но не присутствующим в интерфейсе (Scheduled)ExecutorService
. Это означает, что использование этого, вероятно, влечет за собой определенное поведение конкретной реализации, которое вы не можете полностью контролировать.
Из Javadoc метода REMOVE на ThreadPoolExecutor
:
/**
* Removes this task from the executor's internal queue if it is
* present, thus causing it not to be run if it has not already
* started.
*
* <p> This method may be useful as one part of a cancellation
* scheme. It may fail to remove tasks that have been converted
* into other forms before being placed on the internal queue. For
* example, a task entered using {@code submit} might be
* converted into a form that maintains {@code Future} status.
* However, in such cases, method {@link #purge} may be used to
* remove those Futures that have been cancelled.
*
* @param task the task to remove
* @return true if the task was removed
*/
Обратите внимание, часть о реализации, может быть, преобразующих Runnable
вы передаете в другую форму, что делает его невозможным для метода удалить() работать при вы передаете ему тот же экземпляр Runnable
, который вы использовали для отправки работы. Кроме того, обратите внимание, что нет гарантии, что ваше удаление будет работать, все зависит от того, будет ли уже запущена задача, и в этом случае вам нужно проверить условия гонки. Поэтому я бы посоветовал вам не использовать этот метод.
О вашем назначении ScheduledThreadPoolExecutor
, возможно, вы неправильно поняли javadoc. Во-первых, я бы также придерживался, по возможности, заводских методов, предоставляемых классом Executors
для создания пула. документация Javadoc для Executors.newScheduledThreadPool(int)
состояний:
/**
* Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle.
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
*/
Что означает ИНТ аргумент является «размером основного пула». Здесь ключевое слово - ключевое слово. Если вы переходите к реализации, он фактически использует тот же метод, который вы вызывали в своем фрагменте, поэтому на самом деле никаких изменений здесь нет. Я сохраняю вам немного чтения здесь, но размер «основного» пула - это минимальное количество потоков, которые будут поддерживаться в пуле (как только они будут запущены, пул обычно не превентивно создает потоки, но это реализация, а не контракт, насколько я помню). Это не имеет никакого отношения к максимальному количеству потоков. На самом деле, если вы еще больше развернетеся, вы увидите, что созданный вами конструктор в конечном итоге построит неограниченный пул, который может порождать столько потоков, сколько необходимо.
Как следствие, задания, которые вы отправляете в пул, могут выполняться одновременно.Если вам нужен однопоточный пул, вы можете использовать фабричный метод Executors.newSingleThreadedScheduledExecutor
.
И, наконец, есть необходимость отмены работы. Итак, как отменить работу, которая была подавлена? Ну, когда вы отправляете задание, ExecutorService
экземпляров обычно возвращают объект Future
. Этот объект Future
имеет встроенную логику отмены. Это позволяет вам установить флаг отмены на отправленном задании (что не позволит ему активироваться, если он еще не запущен), и если он уже запущен, он также может спровоцировать прерывание потока.
Надеюсь, что это немного разъяснило семантику.
Ничего себе, столько всего для простого недоразумения. Я надеялся на «о, ты просто забыл ...» Это отличное объяснение, и я ценю время, которое ты вложил в него. Похоже, я кое-что прочитал. Исполнители явно не работают вообще, как я думал, они это сделали. – NickGlowsinDark