Поток отправителя DatagramPacket работает слишком быстро - PullRequest
0 голосов
/ 24 апреля 2011

Я написал поток Java (Runnable), чтобы в основном хранить список DatagramPackets, и если размер списка> 0, он отправит первый элемент в списке.

Похоже, что если я не помещу большой сон в метод run, поток перестанет отвечать на запросы

public void run()
  {
    while ( true )
    {
      if ( _packetQ.size() > 0)
      {
        try
        {
          _socket.send( _packetQ.remove() );
        }
        catch ( IOException ex )
        {
          System.err.println( "Error sending packet" );
          System.err.println( ex );
        }
      }
    }
  }

_packetQ - это связанный список пакетов дейтаграмм.

В любом случае, я могу остановить блокировку потока или запустить его только тогда, когда packetQ.size ()> 0

Спасибо, SO

ОБНОВЛЕНИЕ : О, дорогие, пакеты даже не помещались в очередь из-за ошибки в коде, просто потрачен час на отладку этого. Спасибо за ответы **

Ответы [ 4 ]

4 голосов
/ 24 апреля 2011

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

1 голос
/ 24 апреля 2011

Я не уверен, почему вы хотите отправлять датаграммы в фоновом режиме и почему вы просто не отправляете данные сразу в вызывающем потоке. Выбранный вами подход полезен для блокировки ввода-вывода или даже NIO, но не слишком для UDP. UDP не ждет, поэтому нет смысла передавать эту работу другому потоку.

Я предлагаю вам написать цикл таким образом;

  • Вы можете остановить поток прерыванием.
  • дождитесь готовности данных для отправки.
  • распечатать трассировку стека для исключения.

пример кода

private final BlockingQueue<DatagramPacket> _packetQ = new LinkedBlockingQueue<DatagramPacket>();

public void run() {
    while (!Thread.interrupted()) {
        try {
          _socket.send(_packetQ.take());
        } catch (IOException ex) {
          ex.printStackTrace();
        }
    }
}
1 голос
/ 24 апреля 2011

Вы можете добавить что-то подобное в свой первый while (true) цикл:

while (_packetQ.size() == 0) {
    Thread.sleep(10);
}

Вместо этого предпочитайте использовать LinkedBlockingQueue, см. этот ответ в качестве примера.1008 *

0 голосов
/ 24 апреля 2011

Избавьтесь от проверки размера и просто дайте ему заблокироваться в методе remove)).Убедитесь, что вы используете реализацию очереди с блокирующим поведением, конечно, как это предлагается в других ответах.В данный момент вы просто вращаетесь бессмысленно, а size () == 0.

...