简体   繁体   English

多线程程序运行速度比单线程慢

[英]Multi-Threaded program runs slower than single threaded

I was trying to solve Euler Project .我试图解决Euler Project Gist here .要点在这里 Yes, I get it, there is no algorithm used - I am not trying to.是的,我明白了,没有使用算法 - 我不想。 The question is, the 2nd file is using an ExecutorService to find the values - I understand that the result will not be correct but it is crawling compared to single threaded one.问题是,第二个文件正在使用ExecutorService来查找值 -我知道结果将不正确,但与单线程相比,它正在爬行。 I thought creating threads itself might have overhead reduced the pool size to 4 (I have an eight core processor) but that did nothing.我认为创建线程本身可能会将池大小减少到 4(我有一个八核处理器),但这没有任何作用。

Earlier I had also used similar approach to significantly speed up thumbnail generation using multiple threads.早些时候,我也使用类似的方法来显着加快使用多线程的缩略图生成。 But I am not able to understand what might be causing the slowness of this particular case.但我无法理解是什么导致了这种特殊情况的缓慢。 I am not trying to get the correct solution - I understand that I should do that first and then attempt anything else.我不是想得到正确的解决方案 - 我知道我应该先这样做,然后再尝试其他任何事情。 What is that I doing it wrong.我做错了什么。 I am not coming here with intention to find a solution to the problem but I want to understand why is it slow.我来这里并不是为了找到问题的解决方案,但我想了解为什么它很慢。 I have used static variables that are accessed by Threads.我使用了线程访问的static变量。 Could that be an issue ?这可能是个问题吗?

I understand that the result will not be correct but it is crawling compared to single threaded one我知道结果将不正确,但与单线程相比它正在爬行

I kill the program after 5-6 minutes of execution since it is running very slowly我在执行 5-6 分钟后终止程序,因为它运行得很慢

First off, I assume you are using a Executors.newFixedThreadPool() which allocates a fixed number of threads and not a cached thread pool.首先,我假设您使用的是Executors.newFixedThreadPool() ,它分配固定数量的线程而不是缓存的线程池。

It seems to me that you may be creating some huge number of jobs and you program is running out of memory.在我看来,您可能正在创建大量作业,而您的程序内存不足。 As you fill up memory the JVM works harder and harder on GC which shows up as your process getting slower and slower.当您填满内存时,JVM 会在 GC 上越来越努力地工作,这表现为您的进程越来越慢。 You could connect to the application using jconsole to verify the number of threads and the memory.您可以使用 jconsole 连接到应用程序以验证线程数和内存。 You could also do a thread-dump on it ( kill -QUIT pid ) and see how many jobs you have forked.您还可以对其进行线程转储( kill -QUIT pid )并查看您分叉了多少作业。

If you are creating some huge number of jobs and your ExecutorService just can't keep up, then you will need to throttle the job production.如果您正在创建大量作业而您的ExecutorService无法跟上,那么您将需要限制作业生产。 There are a couple different ways to do that.有几种不同的方法可以做到这一点。 Here's what I use:这是我使用的:

Process Large File for HTTP Calls in Java 在 Java 中处理 HTTP 调用的大文件

Couple other solutions linked from there.从那里链接的其他解决方案。

I thought creating threads itself might have overhead reduced the pool size to 4 (I have an eight core processor) but that did nothing.我认为创建线程本身可能会将池大小减少到 4(我有一个八核处理器),但这没有任何作用。

Yeah this doesn't seem like a processor issue.是的,这似乎不是处理器问题。 I would move it back to 8. If this really makes the box unusable then try 7 or 6 threads in your ExecutorService .我会将它移回 8。如果这确实使该框无法使用,请在ExecutorService尝试 7 或 6 个线程。

Edit:编辑:

After looking at the code more, you are doing a bunch of unsynchronized data updating that is going to cause strange results.在更多地查看代码后,您正在执行一堆不同步的数据更新,这将导致奇怪的结果。 Anytime you modify shared memory (in your case shared static fields) then you are going to have to have some synchronization both in terms of mutex ( ++ ) and memory sharing.任何时候你修改共享内存(在你的情况下是共享static字段),那么你将不得不在互斥锁( ++ )和内存共享方面进行一些同步。

I'd consider using AtomicLong and others if you can but you should read some threading tutorials on shared memory and synchronization: http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html如果可以,我会考虑使用AtomicLong和其他人,但您应该阅读一些关于共享内存和同步的线程教程: http : //docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM