0

我编写了一个 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 时运行

谢谢

更新:哦,亲爱的,由于代码中的错误,数据包甚至没有被推送到队列中,只是浪费了一个小时的调试时间。感谢您的回复**

4

4 回答 4

4

您可以将链表替换为LinkedBlockingQueue静默等待新数据到达的链表。

于 2011-04-24T11:48:27.077 回答
1

while (true)您可以在第一个循环中添加类似这样的内容:

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

虽然更喜欢使用 a LinkedBlockingQueue,但请将此答案视为示例。

于 2011-04-24T11:48:12.260 回答
1

我不确定您为什么要在后台发送数据报,以及为什么不立即在调用线程中发送数据。您采用的方法对于阻塞 IO 甚至 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();
        }
    }
}
于 2011-04-24T18:47:53.267 回答
0

摆脱大小测试,让它在 remove)) 方法中阻塞。确保您使用具有阻塞行为的队列实现,当然正如其他答案中所建议的那样。目前你只是在 size() == 0 时毫无意义地旋转。

于 2011-04-24T13:22:34.273 回答