如何使用线程模拟java中的非阻塞i / o

时间:2010-10-09 20:25:43

标签: java sockets datagram

我正在编写涉及服务器和许多客户端的简单应用程序。我必须使用DataGramSocket。应用程序是通过控制台在聊天中简单地交换消息。但是.readLine()和ds.receive()中的两个操作都是阻塞的,并且将它们放在单独的线程中没有帮助,因为阻塞i / o也会阻塞线程。任何身体都可以告诉我如何在没有nio的情况下做到这一点

3 个答案:

答案 0 :(得分:1)

如果您的线程仅专用于通过网络发送或接收数据,则线程阻塞不会成为问题,因为只有该专用线程才会被阻止。

然后,让我们考虑一下这个解决方案对应用程序中线程数的影响:

  • 如果每台服务器只有少量客户端,那么每个客户端有2个I / O线程不是问题。
  • 如果每个服务器有很多客户端,那么您应该接受这样一个事实,即他们的某些请求不会立即处理,只有工作线程可用。您可以尝试生成与客户端一样多的I / O线程,但单个JVM实例可以拥有的线程数有限制。确切的数字取决于JVM可用的堆大小以及您的体系结构是32位还是64位,请参阅here

如果您对处理大量客户的一般任务感兴趣,here是关于此问题的经典网络论文。

答案 1 :(得分:0)

首先,您应该使用java.nio来获取非阻塞I / O.假设你不能,出于某种原因......

您可以使用DatagramSocket和工作队列轻松地让服务器处理来自多个客户端的数据,例如java.util.concurrent.ThreadPoolExecutor。

这个想法是你有一个接收器线程读取套接字,并且接收每个数据报,包装在“ReceivedDatagram”对象中并放到工作队列中。工作队列有一个线程池,其线程出队并处理每个数据包;如果数据包需要响应,则线程在阻塞之前发送响应(阻塞)以使另一个ReceivedDatagram出列。

要异步发送数据,只需在工作队列中放置一个“SendDatagram”对象,该对象表示要发送的DatagramPacket。

注意,您将使用Datagram.receive(DatagramPacket)和Datagram.send(DatagramPacket)。

答案 2 :(得分:0)

您可以通过使用手动生成的线程或更好的线程池(http://www.ibm.com/developerworks/library/j-jtp0730.html)在单独的线程中执行阻止操作来实现此目的