2011-08-20 2 views
4

Этот вопрос, несомненно, задавался в разных формах в прошлом, но не столько для конкретного сценария.Каков правильный способ остановить поток, ожидающий сетевой активности?

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

Например, у меня есть следующая тема:

public class ClientDiscoveryEngine extends Thread { 

    private final int PORT; 

    public ClientDiscoveryEngine(final int portNumber) { 
     PORT = portNumber; 
    } 

    @Override 
    public void run() { 
     try { 
      socket = new DatagramSocket(RECEIVE_PORT); 

      while (true) { 
       final byte[] data = new byte[256]; 
       final DatagramPacket packet = new DatagramPacket(data, data.length); 

       socket.receive(packet); 
      } 
     } catch (SocketException e) { 
      // do stuff 1 
     } catch (IOException e) { 
      // do stuff 2 
     } 
    } 
} 

Теперь бы более правильным будет путь с помощью метода interrupt()? Например, добавив следующий метод:

@Override 
public void interrupt() { 
    super.interrupt(); 
    // flip some state? 
} 

Моя единственная забота, это socket.receive() не без прерываем метод блокировки? Единственным способом, который, как я думал, будет реализовать метод прерывания, как указано выше, в этом методе вызывает socket.close(), а затем обслуживает его в методе run в catch для SocketException. Или, может быть, вместо while(true) используйте какое-то состояние, которое попадает в метод прерывания. Это лучший способ? Или есть более элегантный способ?

Благодаря

ответ

4

Приемный метод, кажется, не быть прерывистым. Вы можете закрыть сокет: документация Javadoc говорит:

Любой поток в настоящее время заблокирован в receive(java.net.DatagramPacket) на этот разъем будет бросать SocketException

Вы также можете использовать setSoTimeout сделать получить метод блок только для небольшое количество времени. После того, как метод вернется, ваш поток может проверить, был ли он прерван, и повторите попытку, чтобы получить еще раз за это небольшое количество времени.

2

Чтобы остановить поток, вы не должны пользователь ни прервать, ни остановить в Java. Лучший способ, как вы сказали в конце вашего вопроса, состоит в том, чтобы петля внутри основного метода контролировалась флагом, который вы можете поднимать по мере необходимости.

Вот старая ссылка об этом: http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Другие способы остановки нити устарели и не обеспечивают максимальный контроль этот. Кроме того, это, возможно, немного изменилось с помощью служб-исполнителей, у меня не было времени узнать об этом еще много.

Кроме того, если вы хотите, чтобы ваш поток был заблокирован в каком-либо состоянии ввода-вывода, ожидая сокета, вы должны дать вашему сокету соединение и время чтения (метод setSoTimeout).

С уважением, Stéphane

+1

Err, нет. прерывание, чтобы остановить поток.На самом деле это единственный способ сделать это, если поток может быть заблокирован в блокирующем вызове, который реагирует на прерывания (например, Thread.sleep, Object.wait, чтение из прерывистого канала и т. Д.). Прочитайте http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html. –

0

Это один из самых легких. Если он заблокирован в гнезде UDP, отправьте сокету сообщение UDP, которое инструктирует принимающий поток «остановить».

Rgds, Martin

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