我们目前有一个程序将消息写入服务器。对于卷测试,我们运行同一程序的许多实例,这很尴尬。我正在开发一个程序,而不是创建用于编写消息的多线程。
但问题是,线程不会以均匀的速度发送消息。相反,有些人甚至在其他人开始前完成发送。请注意,所有线程几乎同时在循环中启动,并发送相同的消息。
有什么可以做的吗?可能是问题的原因是什么?
编辑:我是新手,但我被告知在运行单独的程序实例时这不是问题(与多线程解决方案相反)。
答案 0 :(得分:3)
有什么可以做的吗?可能是问题的原因是什么?
基本上,问题是您的系统存在瓶颈:
您拥有的核心数限制了 1 时实际可以运行的线程数。
操作系统和网络限制了系统可以发送的网络流量。
操作系统和磁盘硬件限制了系统可以处理的文件I / O流量(如果这与此相关)
您的多线程应用程序可能存在内部并发瓶颈;例如等待互斥锁访问共享数据结构的线程。
还会有瓶颈代表您的服务器接受消息的能力,尤其是在负载下。
(一些性能监控可以为您提供一些线索,说明上述哪一项,或者可能是其他一些,在您的案例中最重要。在某些情况下,您可以解决这些问题......)
面对瓶颈,一些Java线程将不可避免地比其他线程运行得慢。关于 你无能为力。这是因为Java线程调度程序没有实现"调度。更广泛地说,网络和磁盘I / O系统也不是。 (它们针对除公平之外的其他因素进行了优化。)
但这是(修辞)问题。某些线程比其他线程花费更长时间真的很重要吗?难道这相当于一些现实生活中的客户比其他客户慢(出于某种原因)?对您来说最重要的是您的服务器在遇到高负载时的行为;即它可以维持的请求率,以及超过该率时会发生什么。
现在有可能你的问题是你创造了太多的线程。 (有些人错误地认为N个线程会给你N次加速!)创建太多线程会浪费资源 2 ,并且由于次要影响会导致性能降低。如果要执行大量任务,更好的方法是使用带有限线程池的ExecutorService
。将任务抛到队列中,让服务处理线程创建等。
我被告知在运行程序的单独实例时这不是问题(而不是多线程解决方案)。
我认为你已被告知"不正确。如果同时启动N个单线程应用程序,则很可能会在执行时间内看到更多变化。 (并且吞吐量会更差'因为你现在有J次预热的开销N次,而不是一次。)
1 - 例如,如果您有8个物理核心或超线程,则会将应用程序限制为一次运行8个线程。在身体上不可能再做了。如果有超过8个可运行的线程,则有些线程将等待安排。
2 - 每个线程使用内存作为其堆栈及其引用的对象。内存占用增加会增加GC开销,影响内存缓存性能。如果您没有足够的物理内存,则会导致过多的分页。