Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Рассматривали ли вы упаковку ExecutorService? Создайте
CleanShutdownExecutorService implements Executor
, который делегирует все вызовы другому исполнителю, но сохраняет фьючерсы в своем собственном списке. CleanShutdownExecutorService может затем иметь метод cancelRemainingTasks (), который вызывает shutdown (), а затем вызывает cancel (false) для всех фьючерсов в своем списке.
Раньше я работал над приложением с длинными запущенными потоками. Мы делаем это при выключении,
BlockingQueue<Runnable> queue = threadPool.getQueue();
List<Runnable> list = new ArrayList<Runnable>();
int tasks = queue.drainTo(list);
Список сохраняется в файл. При запуске список добавляется обратно в пул, поэтому мы не теряем работу.
Поскольку ExecutorService.shutdown () недостаточно, а ExecutorService.shutdownNow () делает слишком много, я думаю, вам нужно что-то написать в середине: запомните все свои представленные задачи и удалите их вручную после (или до) вызова shutdown()
.
Это старый вопрос, но в случае, если это поможет кому-то еще: вы можете установить энергозависимое логическое значение, когда вызываете shutdown (), и каждая отправленная задача завершается, если это логическое значение задано до реального запуска. Это позволит задачам, которые действительно начали завершаться, но не позволит задачам, находящимся в очереди, начать свою фактическую деятельность.
Bombe ответит именно то, что вы хотите. shutdownNow()
останавливает все, используя подход nuke and pave . Это лучшее, что вы можете сделать, если не учитывать реализацию ThreadPoolExecutor
, которую вы используете.
Вы можете попробовать allowCoreThreadTimeOut(true);
readLines
действительно работы самое простое, даже с простым кодом как fn <- readLines("fn.txt")
!
– Partha D.
29 May 2019 в 13:29
readLines
действительно работы самое простое, даже с простым кодом как fn <- readLines("fn.txt")
!
– Partha D.
29 May 2019 в 13:29
readLines
действительно работы самое простое, даже с простым кодом как fn <- readLines("fn.txt")
!
– Partha D.
29 May 2019 в 13:29
readLines
действительно работы самое простое, даже с простым кодом как fn <- readLines("fn.txt")
!
– Partha D.
29 May 2019 в 13:29
readLines
действительно работы самое простое, даже с простым кодом как fn <- readLines("fn.txt")
!
– Partha D.
29 May 2019 в 13:29
Вы можете создать свою собственную очередь задач и передать ее конструктору ThreadPoolExecutor
:
int poolSize = 1; // number of threads
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>();
Executor executor = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, queue);
Когда вы очищаете очередь где-то в вашем коде, остальные задачи не будут выполнены:
queue.clear();
print(linn)
достаточен.
– Assad Ebrahim
7 April 2014 в 04:41
print(linn)
достаточен.
– Assad Ebrahim
7 April 2014 в 04:41
print(linn)
достаточен.
– Assad Ebrahim
7 April 2014 в 04:41
print(linn)
достаточен.
– Assad Ebrahim
7 April 2014 в 04:41
print(linn)
достаточен.
– Assad Ebrahim
7 April 2014 в 04:41
Не работает awaitTermination(long timeout, TimeUnit unit)
после выключения?
executor.shutdown (); executor.awaitTermination (60, TimeUnit.SECONDS)
Сумасшедшее и нечистое решение, которое может сработать (не совсем продуманно или протестировано), состоит в том, чтобы перезаписать interrupt()
ваших WorkerTasks, которые только в том случае, если установлено какое-то глобальное значение, отказываются закрываться, когда к ним вызывается interrupt()
by shutdownNow ().
Что должно позволить вам использовать shutdownNow()
нет?
Попросите ваш пул потоков завершить работу, getQueue, для каждого результата в отдельные Runnables, удалить каждый Runnable, используя метод remove. В зависимости от типа очереди, вы можете остановить удаление на ранней стадии на основе возвращаемых значений.
По сути, это захват очереди и ее очистка, только очистка с помощью методов, которые работают. Вместо того, чтобы вручную запоминать все представления, вы используете тот факт, что пул потоков уже должен запомнить все представления. Однако вам, вероятно, нужно будет сделать защитную копию очереди, поскольку я думаю, что это живое представление, и поэтому удаление, вероятно, вызовет исключение одновременной модификации, если вы выполняли итерацию / для каждого для живого представления.