Механізм переривання потоку - найкращий спосіб отримати (співпрацюючий) потік, щоб відповісти на запит, щоб зупинити те, що він робить. Будь-який потік (включаючи сам потік, на мою думку) міг би викликати interrupt()Thread.
На практиці звичайні випадки використання interrupt()включають певний фреймворк або менеджера, який каже деякий робочий потік зупинити те, що вони роблять. Якщо робочий потік "поінформований про переривання", він помітить, що він був перерваний через виняток або періодично перевіряючи його перерваний прапор. Помітивши, що його було перервано, добре вихований потік відмовиться від того, що робить, і закінчить сам.
Припускаючи наведений вище варіант використання, ваш код, ймовірно, буде перерваний, якщо він запускається в рамках Java або з якогось робочого потоку. І коли він переривається, ваш код повинен відмовитися від того, що він робить, і змусити себе закінчити найбільш підходящими засобами. Залежно від того, як був викликаний ваш код, це може бути зроблено шляхом повернення або викидання відповідного винятку. Але це, мабуть, не повинно дзвонити System.exit(). (Ваша програма не обов'язково знає, чому її було перервано, і вона точно не знає, чи є інші потоки, які потрібно перервати фреймворком.)
З іншого боку, якщо ваш код не призначений для роботи під контролем якоїсь основи, ви можете стверджувати, що InterruptedExceptionце є несподіваним винятком; тобто помилка. У цьому випадку ви повинні поводитися з винятком, як з іншими помилками; наприклад, оберніть його у неперевіреному винятку, і ловіть та реєструйте його в той самий момент, коли ви маєте справу з іншими несподіваними неперевіреними винятками. (Або ж ваша програма може просто ігнорувати переривання і продовжувати робити те, що робила.)
1) Якщо я ніколи не перериваю інші потоки сам, що може викликати InterruptedException?
Одним із прикладів є те, якщо ваші Runnableоб’єкти виконуються за допомогою служби ExecutorServiceі shutdownNow()викликається в службі. І теоретично, будь-який сторонній пул потоків або система управління потоками може законно зробити щось подібне.
2) Якщо я ніколи не перериваю інші потоки сам, використовуючи interrupt () ... що означає InterruptedExceptionтоді? Що я повинен робити, ловлячи одного? Вимкнути мій додаток?
Вам потрібно проаналізувати кодову базу, щоб з’ясувати, що interrupt()і чому робить дзвінки. Як тільки ви це зрозуміли, ви зможете зрозуміти, що >> ваша << частина програми повинна робити.
Поки ви не знаєте, чому InterruptedExceptionкидають, я б порадив розглядати це як серйозну помилку; наприклад, надрукуйте стек у файл журналу та вимкніть програму. (Очевидно, це не завжди правильна відповідь ... але справа в тому, що це "помилка", і на неї потрібно звернути увагу розробника / супровідника.)
3) Як дізнатися, хто / що телефонує interrupt()?
На це немає хорошої відповіді. Найкраще, що я можу запропонувати, - це встановити точку зупинки на Thread.interrupt()і переглянути стек дзвінків.