我正在开发一个1到多个服务器客户端应用程序,这是一个小项目。
由于套接字IO阻塞。我正在寻找解决方案。
有人能告诉我这2种解决方案的优劣是什么?
由于
答案 0 :(得分:5)
这两种方法都没有错。如果你有有限的客户端,第二个选项就足够了(甚至可能基于多核架构而茁壮成长),否则让java.nio管理你的资源可能是有益的。
请参阅同一主题的this question以及this other帖子,或为什么不考虑this blog post反对在大多数情况下使用java.nio。
答案 1 :(得分:3)
您可以使用简单的InputStream / OutputStream(或Reader / Writer)API,并将Streams包装在一起。在my current project中,我正在使用一堆
而另一方面是接收方。这非常舒服,因为您只需处理程序逻辑中的顶层(其余部分主要是每个构造函数调用)。
每个连接都需要一个新的线程(甚至是一对线程,具体取决于架构)。
(在我的项目中,我为每个连接都有一个MessageParser-Thread,然后将单个作业提供给ThreadPool,然后这些作业可以写入一个或多个打开的连接,而不仅仅是产生它们的连接。当然,写作是同步的。)
每个线程需要相当多的堆栈空间,如果您使用的是资源有限的计算机,则可能会出现问题。
对于短期连接,实际上你不希望每个连接都有一个新线程,但是只需要在ThreadPool上执行一个新的Runnable,因为新线程的构造需要一些时间。
如果你有这样一个有多次转换的多层架构,你必须自己安排。有可能:
然而,管理开销非常麻烦,因为您必须跟踪数据的位置。 (我实际上每个连接有两个管道,一个或两个线程管理所有管道中的数据,在这个等待一个Selector上的套接字上的新数据(或者在那里的新空间,在传出的情况下)。解析消息后的实际处理仍然发生在ThreadPool中的生成的Runnables中。)
您只需要少量线程。这实际上是我试图异步执行此操作的原因。它工作(使用相同的同步客户端),但比我的多线程解决方案慢,所以我把它放回去,直到我们的内存耗尽太多线程。 (到目前为止,同时没有那么多连接。)
答案 2 :(得分:1)
NIO获胜,我可以在我想要的时候实际停止线程。学习NIO现在很困难,但是正确使用缓冲区几乎从未在任何地方解释过。其中一个原因,我相信,人们不能为了exrta的利益而挤压NIO。
NIO的其他部分是大多数开发人员无法编写和使用状态机,因此他们最终会过多地复制缓冲区。
答案 3 :(得分:0)
NIO的性能是合理的,并且应该使用不超过#cores线程,乘以应用程序的IO因子,其中IO因子是等待磁盘IO完成的应用程序的百分比。
原因很简单。当你有#cores worker时,每个worker可能被绑定到一个cpu核心并且可以将它最大化。工作人员越多,上下文切换越多,这正是你不想要的,以及为什么你首先使用NIO。
如果工作人员必须等待IO,他们可以处理其他请求,因此使用更多的工作人员而不是核心来获得完全的cpu利用率。
如果您使用线程,您将获得以下优势:
答案 4 :(得分:0)
我试过Apache MINA,这真的很棒。我强烈推荐它。