2013-05-13 2 views
1

В моем приложении каждый запрос имеет свой собственный поток. Я использую JMX/JConsole для их мониторинга, измерения прошедшего времени. Если запрос требует слишком много времени, я хотел бы остановить его, прервав основной поток. В методе, который я вызываю из JConsole, я перебираю список потоков и вызываю прерывание() в нужном экземпляре.
Однако просто вызов метода interrupt() в экземпляре потока только устанавливает флаг, поэтому мне нужно также бросить InterruptedException. Но это InterruptedException будет применяться к currentThread вместо потока, который я действительно хочу остановить. Любой намек на то, как закрыть отмеченный поток?Как отключить поток от другого?

while (iterator.hasNext()) { 
        RequestHolder rh = iterator.next(); 
        if (rh.getThread().getId() == threadId) { 
         rh.getThread().interrupt(); 
         if(rh.getThread().isInterrupted()){ 

          throw new InterruptedException(); 
         } 
        } 
       } 

ответ

2

Но это InterruptedException будет применяться к currentThread вместо нити я на самом деле хочу, чтобы остановить.

Вы можете проверить статус прерывания любой нити, используя isInterrupted. Однако, если вы не знаете, как и когда прерывается потребление, это не рекомендуется в качестве подхода с черным ящиком.

Любой намек на то, как закрыть отмеченную нить?

Вы не можете полностью отключить нить из другой резьбы.

Но это очень просто. В потоках, которые работают, регулярно проверяйте на Interruption, например, на захват цикла InterruptedException для блокировки функций. Когда вы видите прерывание в потоке, завершите его. В некотором смысле, Threads реализуют свою собственную политику завершения.

+0

только для заметки - некоторые блокирующие сторонние функции могут обернуть InterputException в некоторых других, например IOException или так (Axis). поэтому всегда проверяйте, не перепутаны ли они. – JIV

1

Нельзя использовать бросок InterruptedException. Ваш блок if (rh.getThread().isInterrupted()) можно удалить.

Каждый поток должен контролировать свое собственное прерывистое состояние и должен выйти изящно, когда видит, что он был прерван.

Обычно код выглядит примерно так:

try { 
    InputStream in = socket.getInputStream(); 
    while (in.read(buffer) >= 0) { 
     if (Thread.interrupted()) { 
      logger.log(Level.FINE, "Interrupted; exiting"); 
      break; 
     } 

     // Process request buffer here 
    } 
} catch (InterruptedIOException e) { 
    logger.log(Level.FINE, "Interrupted; exiting", e); 
} 

Если вы используете каналы, вы хотите, чтобы поймать ClosedByInterruptException, а также.

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^