Правильно ли иметь поле ScheduledFuture в задаче Runnable?
С чисто технической точки зрения, я не думаю, что существует какая-либо проблема в сохранении ScheduledFuture в случаеКласс Task, который реализует Runnable, потому что ваш экземпляр класса Task будет просто сохранять его как информацию о состоянии, которую вы можете использовать позже в своем коде, как вы это делали в методе stopTask () .Кроме того, просто отметим, что здесь вы используете PeriodicTrigger, что означает, что поток будет продолжать выполняться после предоставленного интервала времени 100 мс, если задача не будет отменена.
ПРИМЕЧАНИЕ. Убедитесь, что фактический метод run () никоим образом не изменяет будущее переменной класса.(хотя в этом вопросе это не сделано, ваш реальный код также не должен иметь таких изменений в будущей переменной внутри метода run ())
собирать задачи в ArrayList?Должен ли я использовать CopyOnWriteArrayList?
Использование ArrayList здесь не повредит, так как вы используете это из любого многопоточного контекста.Если этот список должен был использоваться в многопоточном контексте, то вы, вероятно, могли бы подумать об использовании CopyOnWriteArrayList.Чтобы быть точным, ваш класс ServiceTest имеет метод registerTasks (), который изменяет / обращается к вашему списку, и этот метод не вызывается многопоточным способом согласно коду, показанному в вопросе.Таким образом, здесь нет необходимости в CopyOnWriteArrayList.
Также, при необходимости, вы также можете проверить, была ли задача отменена или нет, используя возвращенное логическое значение из вызова метода cancel.Возможно, вы захотите использовать его для выполнения любых дальнейших действий.
ОБНОВЛЕНИЕ: О, хорошо, я пропустил эту модификацию через итератор.Я согласен, что метод stopTask () может быть доступен многопоточным способом, если он может быть вызван через контроллер REST.Однако CopyOnWriteArrayList не поддерживает метод remove () в своем итераторе () на тот случай, если вы думаете об этом.Кроме того, использование CopyOnWriteArrayList рекомендуется только в том случае, если у вас больше операций чтения, чем операций записи в списке.На самом деле он предназначен для безопасных обходов, где большинство операций чтения с использованием итератора.Я бы предложил синхронизировать метод stopTask () или использовать Collections.synchronizedList (tasks)