2014-10-03 38 views
0

我有一个简单的客户端服务器应用程序使用套接字进行通信。一种可能性是每次客户端向服务器发送一些东西时关闭套接字。保持java套接字打开 - 如何检查新数据是否可用?

但我的想法是保持连接始终打开,即如果客户端联系服务器,应将连接放入队列(例如LinkedBlockingQueue)并保持打开状态,这会提高性能。

如何在服务器中检查队列中是否有可用的新数据?我能想象的唯一事情就是不断迭代整个队列,并检查每个套接字是否有新数据。但是这会非常低效,因为如果我有几个线程在队列上工作,当一个线程扫描队列时队列就会被阻塞。

或者是否有可能在套接字上注册回调函数,以便套接字通知线程数据已准备好?

+0

套接字的InputStreams有几个读取方法,可以阻止当前线程,直到有可用的东西。你通常需要做套接字网络多线程。这意味着每个客户端都有一个接收线程,将数据存储在主线程需要时可以检索到的地方。 (评论,因为不知道这是否是这个问题) – Felk 2014-10-03 23:16:55

回答

2

但我的想法是保持连接始终打开,即如果客户端联系服务器,连接应放入队列(例如LinkedBlockingQueue)并保持打开状态,则会提高性能。

保持连接打开将提高性能,尽管存在扩展问题:打开的套接字使用内核资源。 (虽然我不会使用队列...)

如何在服务器中检查队列中的套接字是否有新数据?

如果你有一个数量的插座不同客户的,你要处理的(大致)订单数据,它到来时,常见的有两种方法:

  • 创建每一个线程套接字,并让每个线程简单地进行读取。这将(自然)阻塞线程直到数据可用。

  • 使用NIO通道选择器机制(请参阅Selector),该机制可让您找出一组I/O通道中的哪一组准备好读取或写入。每个插槽

主题往往是耗资源(线程堆栈),并在所有的,如果你有多个线程同时处于活跃不能很好地扩展。 (上下文切换太多,线程调度器上的负载太多)。相比之下,选择器映射到主机操作系统提供的本机系统调用,因此它们高效且响应...如果智能地使用。

(你也可以得到无阻塞通道的插槽,和他们进行轮询循环的方式,但是这不会是任何有效的或有反应。)

正如你所看到的,没有任何的这些想法与队列一起工作。要么你有多个线程处理一个套接字,要么你有一个线程处理套接字的数组或(数组)列表。队列抽象不是为索引或迭代而设计的。

或者是否有可能在套接字上注册回调函数,以便套接字通知线程数据已准备好?

查看@ Lolo的回答。

+0

感谢您的回答。假设我有一个在套接字线程接受连接时创建的线程。当线程现在将连接放到队列中,然后线程终止时,这是否也会关闭连接? – machinery 2014-10-04 13:11:01

相关问题