我的目标是处理线程内部的WebSocket连接。如果我使用in a new Thread,服务器可以处理的WebSocket连接的数量是未知的。如果我使用in a Thread pool,服务器可以处理的WebSocket连接的数量就是线程池大小。
我不确定可用处理器和线程之间的相关性。一个处理器一次执行一个线程吗?
我的预期结果是:创建比可用处理器更多的线程是不可取的,您应该重新设计如何处理WebSocket连接。
在一个新的线程中
final Socket socket = serverSocket.accept();
new Thread(new WebSocket(socket, listener)).start();在线程池中
final ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
final Socket socket = serverSocket.accept();
es.execute(new WebSocket(socket, listener));为了避免混淆,WebSocket类是实现Runnable的自定义类。据我所知,Java没有WebSocket服务器,只有WebSocket客户机。
发布于 2021-08-16 01:26:17
做线。一千,如果你愿意的话。
在CPU核心级别,下面是正在发生的事情:
问题是,有两种方式可以支付这一费用:您可以切换到另一个线程,这是各种上下文切换。或者,您有一个线程运行所谓的‘异步’代码,它自己管理所有这些东西,然后跳到另一个工作中去,但是仍然有一个上下文开关。
具体来说,CPU现在再也不能与内存进行交互了,过去十年也没有了。它们只能与CPU缓存页交互。实际上,机器代码不再是真正的“直接运行”了,相反,在CPU注意到它即将运行一条涉及到某些内存的指令之后,它会将内存命令(毕竟,CPU不能再与它交互)映射到缓存中的正确位置。它还会注意到,如果您试图用机器代码访问的内存根本不在与该核心相关联的缓存页中,在这种情况下,它将触发一个缺页中断,从而导致CPU /内存总线的内存子系统“退出一个页”(将所有内存写回主内存),然后加载到正确的页中,然后CPU才会继续运行。
这一切都发生在“引擎盖下”,您不必编写代码来切换页面,而是由CPU自动管理它。但这是一个沉重的代价。不像线程开关那么重,但几乎和线程开关一样重。
结论:线程很好,有很多线程。它确保CPU在有工作要做的时候不会手忙脚乱。请注意,有许多博客文章赞美异步的优点,声称线程“不缩放”。他们错了。线程扩展得很好,异步代码也一直在支付上下文切换的费用。。
如果您没有意识到,“异步代码”是一种尝试永不休眠的代码(永远不要做一些等待的事情。因此,您不必编写'getMeTheNextBlockOfBytesFromTheNetworkCard',而是编写:“onceBytesAreAvailableRunThis(代码转到这里)”。用java编写异步代码是可能的,但与使用线程相比非常困难。
即使在非常罕见的情况下,异步代码将是一个重大的胜利,Project已经接近完成,这将使java能够拥有您可以手动管理的类似线程的东西(所谓的纤维)。这就是OpenJDK为此选择的路线。在这个意义上,即使你认为异步是答案,不,它不是。等待项目织机完成,相反。如果您想阅读更多内容,请阅读你的功能是什么颜色的?和回调地狱。这两篇文章都不是特定于java的,而是涵盖了异步中固有的一些更严重的问题。
https://stackoverflow.com/questions/68796254
复制相似问题