【问题标题】:Better solutions for checking if data is in stream using Java stream functions?使用 Java 流函数检查数据是否在流中的更好解决方案?
【发布时间】:2011-07-31 12:35:24
【问题描述】:

我有一个需要读取数百个套接字通信的应用程序。

我正在使用具有线程数上限的 ThreadPool 来服务这些套接字。如果套接字没有传入消息,这会导致所有线程阻塞。

我目前使用 100 毫秒的 soTimeout 来避免永久阻塞。我不喜欢这种方法,因为它可能会在它开始接收输入时超时。

还有其他方法可以解决这个问题吗?

我尝试使用 ObjectInputStream.isAvailable() 进行检查,但无论流中是否有数据,它总是返回 0。

我找不到任何其他方法来检查流中是否有数据。这将是理想的,因为那时我可以检查是否有数据,如果没有,则继续下一个流。

【问题讨论】:

  • 每个连接没有一个线程有什么原因吗?它确实可以解决一些开销,但对于数百个线​​程都可以正常工作。
  • 确实如此,但实际上确实如此,我对 Sanjay 的回答的第四和第五条评论说明了为什么我不希望每个连接一个线程。
  • 我只是想偷看一下 ObjectInputStream,如果有什么东西,把它推回去读,否则没读。也许使用PushBackStreams之类的东西你们怎么看?
  • 如果你有 10K 线程,你可以让大约一个完整的核心忙于交换线程。您不能将 PushBackStreams 与 ObjectInputStream 一起使用,因为流是有状态的。

标签: java sockets objectinputstream


【解决方案1】:

这正是 NIO 框架旨在解决的问题。不幸的是,使用原始 NIO 比使用阻塞 IO 要困难一些。如果可以的话,我的建议是尝试framework like Netty,这会减轻你的工作负担。

【讨论】:

  • 我绝对会这样做。由于时间有限,我目前的情况无法及时阅读 NIO 并重新实现整个应用程序,除此之外还有什么方法可以推荐吗?
  • Netty 有很好的文档记录,并附带了大量的示例代码。如果这在时间上仍然是一个问题,那么彼得提出了一个很好的观点。只需使用cachedThreadPool 而不是具有硬限制的池。您的系统中是否存在大量线程问题?
  • 嗯,不具体。原因是我测试过,发现网上一些文章显示创建线程来管理大量连接的内存开销很快就会变得惊人的大。
  • 我正在考虑,比如 10 000 个客户。这意味着我有 10 000 个线程对象。可能有数千人可能几乎在同一时间解除阻塞。由于每个客户端都可以向许多其他客户端(例如聊天室)广播,因此当我拥有如此多的线程时,我将不得不处理大量的争用问题,我当然希望避免这种情况。
  • 好的,首先,你确定是 10K 吗?其次,10K“活跃”客户端是一些严重的流量。在具有 3GiB RAM 和 32 位 Windows 操作系统的 4 核机器上,我可以生成大约 11K 线程,每个线程具有 128K 堆栈大小。如果您有某种很棒的硬件(至少 8Gib RAM 和 8 个内核),那么生成 10K 线程应该没什么大不了的。但请您深思:您真的需要 10K 的“活跃”客户吗?
【解决方案2】:

你可以给蔚来一个机会。 使用 Selector 和 SocketChannels 等待数据,而不是为每个套接字创建线程。

Selector

SocketChannel

【讨论】:

  • 我绝对会这样做。由于时间有限,我目前的情况无法及时阅读 NIO 并重新实现整个应用程序,除此之外还有什么方法可以推荐吗?
  • 我有一个非常疯狂的想法。当您打开一个套接字时,获取它的 InputStream,并用您自己的实现包装它,该实现需要超时并在没有数据到达时返回。这样你就可以在每个套接字的 InputStream 上运行串行并检查是否有可用的数据。 (我猜这有点像 NIO..)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2021-12-26
  • 2019-11-22
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多