【问题标题】:Java socket server without using threads不使用线程的 Java 套接字服务器
【发布时间】:2018-08-23 20:53:47
【问题描述】:

我正在开发一个应用程序,它应该非常轻量级并且使用最少的线程数。
我的应用程序中需要一个套接字服务器来监控心跳。

ServerSocket listener= new ServerSocket(port);
while (true) {
   Socket socket = listener.accept();

   Runnable thread = new HBClient(this, socket);
   thread.run();
}

这里的问题是我必须为每个客户端使用一个线程。
有没有办法在不使用线程的情况下做到这一点?也许是一种事件驱动的方法来识别客户端何时连接,或者是一种非阻塞方法来接受客户端。(我已经检查了 java.nio,但似乎没有线程就不能使用)

【问题讨论】:

  • 你怎么认为没有(额外的)线程就不能使用 NIO?
  • 按照我的理解,我必须有一个无限循环来等待新客户,就像上面的例子一样。
  • 连接新客户端,读取数据,写入数据。是的,什么都做。不涉及等待,这将使其阻塞 IO。
  • 阅读thisthisthis

标签: java sockets


【解决方案1】:

使用 NIO(对于新 IO,而不是非阻塞 IO),您可以在单个线程上使用 Selector 来处理多个通道,而使用基本 IO,您有一个线程负责一项任务(接受连接或在连接)。

基本前提是您拥有资源,并且单个选择器将“旋转”并选择其中一个来处理需要完成的任何事情(连接、读取、写入)。完成后,将选择另一个资源,依此类推。当然,除非确实有事情要做,否则不会选择资源,并且频道会通过SelectionKey 标志来告知可以执行哪些操作。

然而,使用非阻塞 IO 比基本 IO 更多 harder to program,如果您不处理大量资源,那么 [改进](NIO Performance Improvement compared to traditional IO in Java ) 任何一个。即使您确实想使用 NIO,也建议除非您出于学习目的使用 NIO,否则请使用像 Netty 这样的现有框架,这将使您更容易专注于程序的功能,而不是让 NIO 的复杂性正常工作。

如果您确实想花时间在 NIO 上,有很多关于 SO 的问题可以像 Java NIO Server 那样讨论它

【讨论】:

  • 我测试了选择器。工作完美。谢谢。
【解决方案2】:

没有。即使您尝试实现事件驱动的方法,仍然应该有人监听套接字以引发事件。所以用一个线程基本上是不可能做到这一点的。

但是,您可以在通知连接的客户端时打破无限循环。你不会接受新客户,但你会在一个线程中。

【讨论】:

  • 很遗憾没有。这违背了服务器-客户端的概念。
  • 非阻塞 ServerSocketChannel 完全符合您的想象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 2013-02-11
  • 1970-01-01
相关资源
最近更新 更多