Java 高负载下的并行线程争用

Java 高负载下的并行线程争用,java,multithreading,concurrency,project-reactor,reactor,Java,Multithreading,Concurrency,Project Reactor,Reactor,我有一台四芯的机器。在高负载下,响应时间非常糟糕。这一点非常明显,因为工作队列在高负载下增长,而4个并行线程的消耗速度只能如此之快 Mono.just(stream) .flatMap(handler::handleRequest) .subscribeOn(Schedulers.parallel()) .subscribe(this::response) 类似地,当我得到一个I/O调用的响应时,我会执行一个.publishOn(Schedulers.parallel

我有一台四芯的机器。在高负载下,响应时间非常糟糕。这一点非常明显,因为工作队列在高负载下增长,而4个并行线程的消耗速度只能如此之快

Mono.just(stream)
    .flatMap(handler::handleRequest)
    .subscribeOn(Schedulers.parallel())
    .subscribe(this::response) 
类似地,当我得到一个
I/O
调用的响应时,我会执行一个
.publishOn(Schedulers.parallel())
,以便在CPU调优的线程上处理响应

我正在考虑使用一个有界的弹性调度程序来启动我的管道,并将并行线程仅用于高度CPU密集型任务(POJO操作和哈希计算)。基本上,我在弹性线程上启动管道,并在弹性线程上处理响应

我使用一个无限弹性调度程序对我的应用程序进行了基准测试,结果堆的大小变大了。然而,等待时间肯定要短一些。但是,如果我创建了太多线程,调度开销会在某个时候掩盖较低的等待时间

如何优化我的应用程序?我的目标是每个
JVM
大约800 TPS。是否建议创建这么多线程

类似地,当我得到I/O调用的响应时,我会执行.publishOn(Schedulers.parallel()),以便在CPU调优的线程上处理响应

这就是问题所在。您永远不应该在由调度程序.parallel()启动的线程中执行阻塞调用(您可以使用它,这样做时将抛出并出错)

基本上,我在弹性线程上启动管道,并在弹性线程上处理响应


无需“在弹性螺纹上启动管道”。只要“正常”启动它,然后将阻塞调用卸载到Schedulers.boundederastic()

当我切换到并行时,我已经有了响应。在并行线程上不进行I/O调用。你是说POJO操纵等正在阻止呼叫?此外,我所有的I/O调用都是非阻塞的。最后,我无法在Tomcat的线程上启动管道,因此需要一个线程切换。也许我是个新手,但我不熟悉TPS这个术语?哦,对不起。它是每秒的事务数。