有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

sockets Java线程池与高请求场景中的新线程

我有一些关于REST服务的旧java代码,它对每个传入的请求使用单独的线程。也就是说,主回路将在插座上循环。accept()并将socket交给Runnable,然后Runnable将启动自己的后台线程并调用run on自身。这在一段时间内运行良好,直到最近我才注意到,在高负载情况下,接受处理请求的延迟是不可接受的。当我说令人钦佩地好时,我的意思是它每秒处理100-200个请求,没有显著的CPU使用率。只有在其他守护进程也添加负载时,性能才会下降,并且只有在负载超过5时才会下降。当机器处于其他过程组合的高负载(5-8)下时,从接受到处理的时间会高得离谱(500毫秒到3000毫秒),而实际处理时间则保持在10毫秒以下。这些都在双核centos 5系统上

已经习惯了在网络上使用线程池。NET,我认为线程创建是罪魁祸首,我想我会在java中应用相同的模式。现在我的Runnable是用ThreadPool执行的。Executor(池使用和ArrayBlockingQueue)。同样,它在大多数情况下都非常有效,除非机器负载很高,否则从创建runnable到调用run()的时间也会显示出同样荒谬的时间。但更糟糕的是,在线程池逻辑就绪的情况下,系统负载几乎翻了一番(10-16)。所以现在我在负载加倍的情况下遇到了同样的延迟问题

我的怀疑是,队列的锁争用比之前没有锁的新线程启动成本更糟糕。任何人都可以分享他们的经验,新线程与线程池。如果我的怀疑是正确的,那么有人有其他方法来处理线程池而不存在锁争用吗

我很想让整个系统成为单线程,因为我不知道线程有多大帮助,IO似乎也不是问题,但我确实收到了一些长期存在的请求,这些请求会阻止一切

谢谢, 阿恩

更新:我切换到了Executors.newFixedThreadPool(100);,虽然它保持了相同的处理能力,但负载几乎立即翻了一番,运行12小时后,负载始终保持在2倍。我猜在我的情况下,每个请求一个新线程更便宜


共 (1) 个答案

  1. # 1 楼答案

    测量,测量,测量!它在哪里消磨时间?创建Runnable时会发生什么?Runnable在实例化过程中是否存在阻塞或延迟的情况?延迟期间发生了什么

    事实上,我非常相信从总体上考虑问题,但这种情况下,像这样的意外行为,只需要有一些测量

    运行时环境、JVM版本和体系结构是什么