在利用 Java 的阻塞套接字(我打算独立读写)时,我发现我的两个选择是要么为每个操作专用一个单独的线程,要么使用 setSoTimeout()
轮询超时。 .
在两种实现之间做出选择似乎是内存(线程)与 CPU 时间(轮询)之间的权衡。
我发现许多线程的调度程序和上下文切换可能会出现扩展问题,这些问题可能会超过轮询所花费的 CPU 时间,以及根据收到的数据包大小,从单个线程读取和写入之间可能出现的延迟。或者,如果调整得当,可以使用小型线程池结合多个套接字的轮询来进行扩展。
除了 Java 的 NIO 作为替代方案之外(这超出了本问题的范围),我是否正确理解了可用于处理阻塞套接字的选项?
最佳答案
首先,我认为您已经排除了唯一可以扩展的选项;即使用 NIO。
每套接字线程或轮询都不会扩展。
在线程情况下,每个套接字需要两个线程。 (线程池不起作用。)这会消耗线程堆栈和线程对象的空间,以及 native 线程描述符的内核资源。然后还有一些次要影响,例如上下文切换、额外的 GC 跟踪等。
在轮询情况下,您需要为每个套接字进行定期系统调用。无论您使用一个线程还是一小群线程来执行此操作,系统调用的数量都是相同的。如果轮询更频繁,系统调用率就会增加。如果您轮询的频率较低,您的系统的响应速度就会降低。
据我所知,鉴于您设置的限制,没有其他选项。
<小时/>现在,如果您想找出线程和轮询哪个更好,答案将是“这取决于”。有很多变数:
- 空闲物理内存和空闲 CPU 周期的数量。
- 套接字数量。
- 套接字的相对 Activity 。
- 响应能力要求。
- JVM 中还发生了什么(例如触发 GC)
- JVM 之外还发生了什么。
- 操作系统性能特征。
所有这些加起来构成了一个复杂的场景,可能很难进行数学分析,很难(准确)模拟,也很难进行经验测量。
关于java - 在考虑使用阻塞套接字时,我可以使用哪些选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42730882/