ArrayBlockingQueue - как «прервать» поток, который обрабатывает метод .take () - PullRequest
0 голосов
/ 05 июня 2010

Я использую ArrayBlockingQueue в своем коде. Клиенты будут ждать, пока элемент станет доступным:

myBlockingQueue.take();

Как я могу "закрыть" мою службу, если в очереди нет элементов, а take() ждет элемента в течение неограниченного времени? Этот метод выбрасывает InterruptedException. Мой вопрос: как я могу "вызвать" прерывистое исключение, чтобы take() вышел? (Я также думал о notify(), но, похоже, я здесь не помог ..)

Я знаю, что могу вставить специальный маркерный элемент "EOF / QUIT", но действительно ли это единственное решение?

ОБНОВЛЕНИЕ (относительно комментария, который указывает на другой вопрос с двумя решениями):

один из упомянутых выше с использованием «Объекта отравленной пилюли», а второй - Thread.interrupt():

myBlockingQueue.take() используется НЕ в Thread (расширяющий поток), а скорее реализует Runnable. Кажется, Runnable не предоставляет метод .interrupt()?

Как я мог прервать Runnable?

Ответы [ 3 ]

5 голосов
/ 05 июня 2010

Вы можете реализовать Runnable следующим образом. (Предполагается, что вы запустили Runnable, прежде чем пытаться его прервать)

class MyRunnable implements Runnable {
    private Thread thisThread;
    public void run() {
       thisThread = Thread.currentThread();
       try {
          // do some work
       } catch(Throwable t) {
          t.printStackTrace(); // or log the error.
       } 
    }
    public void interrupt() {
       thisThread.interrupt();
    }
}
1 голос
/ 05 июня 2010

Простой способ - сохранить ссылку на поток, который вы используете для запуска работоспособного, и прервать его при завершении работы.

В качестве альтернативы вы можете использовать пулы потоков для организации потоков для службы. Затем пул потоков отслеживает потоки и управляет ими, включая их прерывание при завершении работы.

Еще один (хакерский и не рекомендуемый способ) - перечислить все запущенные потоки в JVM (используя метод ThreadGroup) и попытаться угадать, какой поток запускает ваш выполняемый (например, анализируя стек каждого потока). *

0 голосов
/ 05 июня 2010

Нашли решение:

Либо используйте, как описано в вопросе, «Отравляющий объект»

или

Прервать поток eitehr с помощью this.interrupt() или, если он используется в режиме Runnable Thread.currentThread().interrupt();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...