java.nio vs每个套接字的新线程

时间:2011-02-02 16:53:03

标签: java multithreading sockets nio

我正在开发一个1到多个服务器客户端应用程序,这是一个小项目。

由于套接字IO阻塞。我正在寻找解决方案。

有人能告诉我这2种解决方案的优劣是什么?

  1. 使用java.nio
  2. 为每个连接的客户端添加一个单独的线程。
  3. 由于

5 个答案:

答案 0 :(得分:5)

这两种方法都没有错。如果你有有限的客户端,第二个选项就足够了(甚至可能基于多核架构而茁壮成长),否则让java.nio管理你的资源可能是有益的。

请参阅同一主题的this question以及this other帖子,或为什么不考虑this blog post反对在大多数情况下使用java.nio。

答案 1 :(得分:3)

个别线程

  • 您可以使用简单的InputStream / OutputStream(或Reader / Writer)API,并将Streams包装在一起。在my current project中,我正在使用一堆

    • MessageFormatter,一个自定义格式类
    • 的PrintWriter
    • OutputStreamWriter
    • DebugOutputStream(自定义类,用于调试目的的副本)
    • DeflatorOutputStream(自定义子类,实际上支持刷新)
    • SSLSocket的OutputStream

    而另一方面是接收方。这非常舒服,因为您只需处理程序逻辑中的顶层(其余部分主要是每个构造函数调用)。

  • 每个连接都需要一个新的线程(甚至是一对线程,具体取决于架构)。

    (在我的项目中,我为每个连接都有一个MessageParser-Thread,然后将单个作业提供给ThreadPool,然后这些作业可以写入一个或多个打开的连接,而不仅仅是产生它们的连接。当然,写作是同步的。)

  • 每个线程需要相当多的堆栈空间,如果您使用的是资源有限的计算机,则可能会出现问题。

对于短期连接,实际上你不希望每个连接都有一个新线程,但是只需要在ThreadPool上执行一个新的Runnable,因为新线程的构造需要一些时间。

非阻塞IO

  • 如果你有这样一个有多次转换的多层架构,你必须自己安排。有可能:

    • 我的MessageFormatter可以写入CharBuffer以及Writer。
    • 用于Char-to-Byte格式化,使用CharsetEncoder / CharsetDecoder(在CharBuffer和ByteBuffer之间传输数据)。
    • 对于压缩,我在Deflater / Inflater周围使用了包装类,它在两个ByteBuffers之间传输数据。
    • 对于加密,我使用SSLEngine(每个连接一个),它也使用ByteBuffers进行输入和输出。
    • 然后,写入SocketChannel(或从另一个方向读取)。

    然而,管理开销非常麻烦,因为您必须跟踪数据的位置。 (我实际上每个连接有两个管道,一个或两个线程管理所有管道中的数据,在这个等待一个Selector上的套接字上的新数据(或者在那里的新空间,在传出的情况下)。解析消息后的实际处理仍然发生在ThreadPool中的生成的Runnables中。)

  • 您只需要少量线程。这实际上是我试图异步执行此操作的原因。它工作(使用相同的同步客户端),但比我的多线程解决方案慢,所以我把它放回去,直到我们的内存耗尽太多线程。 (到目前为止,同时没有那么多连接。)

答案 2 :(得分:1)

NIO获胜,我可以在我想要的时候实际停止线程。学习NIO现在很困难,但是正确使用缓冲区几乎从未在任何地方解释过。其中一个原因,我相信,人们不能为了exrta的利益而挤压NIO。

NIO的其他部分是大多数开发人员无法编写和使用状态机,因此他们最终会过多地复制缓冲区。

答案 3 :(得分:0)

NIO的性能是合理的,并且应该使用不超过#cores线程,乘以应用程序的IO因子,其中IO因子是等待磁盘IO完成的应用程序的百分比。

原因很简单。当你有#cores worker时,每个worker可能被绑定到一个cpu核心并且可以将它最大化。工作人员越多,上下文切换越多,这正是你不想要的,以及为什么你首先使用NIO。

如果工作人员必须等待IO,他们可以处理其他请求,因此使用更多的工作人员而不是核心来获得完全的cpu利用率。

如果您使用线程,您将获得以下优势:

  • 您可以在ThreadLocals中存储会话信息。
  • 您无需以其他方式管理会话信息。

答案 4 :(得分:0)

我试过Apache MINA,这真的很棒。我强烈推荐它。