2014-03-25 304 views
2

我试图解决Euler Project。要点here。是的,我明白了,没有使用任何算法 - 我不是在尝试。问题是,第二个文件正在使用ExecutorService来查找值 - 我知道结果不正确,但与单线程相比,它正在进行爬网。我认为创建线程本身可能会有开销将池大小减少到4(我有一个八核心处理器),但是什么也没做。多线程程序运行速度慢于单线程

早些时候,我还使用similar approach显着加快使用多线程的缩略图生成。但我无法理解可能导致这一特殊情况缓慢的原因。我不是想要得到正确的解决方案 - 我知道我应该先做,然后尝试其他任何事情。我做错了什么?我不打算找到解决问题的方法,但我想了解它为什么会很慢。我使用了线程访问的static变量。这可能是一个问题吗?

+3

有多长线程中运行?如果他们短命,那么这可能不值得。它们在IO上被阻塞了吗?如果您受CPU限制,您只能看到速度提升。 – Gray

+0

这可能是创建几乎无限数量的Runnables(包括用于负数的)的开销 – immibis

+0

@Gray我正在使用'ExecutorService',所以希望所有线程都应该存在,直到找到一个数字 - 由于运行速度非常缓慢,因此需要执行6分钟。我应该再运行一次吗?但是线程中的调用只能持续1-2个毫秒。 在IO上被阻塞 - 现在我只有一行'System.out.println' - 那还能说明我在检查因子中达到的计数吗?与单线程相比,它的运行速度仍然很慢。 – ykesh

回答

2

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

首先,我假设你使用的是Executors.newFixedThreadPool()其线程分配一个固定的数,一个缓存的线程池。

在我看来,你可能正在创造一些大量的工作,你的程序内存不足。当你填满内存时,JVM在GC上越来越难以工作,随着你的进程越来越慢,出现这种情况。您可以使用jconsole连接到应用程序以验证线程数和内存。你也可以在它上面做一个线程转储(kill -QUIT pid),看看你有多少个作业。

如果你的创造了一些大量的工作,而你的ExecutorService只是跟不上,那么你将需要扼制工作生产。有几种不同的方法可以做到这一点。这里是我使用的:

Process Large File for HTTP Calls in Java

夫妇从那里链接其他解决方案。

I thought creating threads itself might have overhead reduced the pool size to 4 (I have an eight core processor) but that did nothing.

是的,这似乎不是一个处理器问题。我会将它移回到8.如果这确实使箱子不可用,请在ExecutorService中尝试7或6个线程。

编辑:

的代码看多后,你做了一堆不同步数据更新的那将会导致奇怪的结果。任何时候你修改共享内存(在你的情况下共享static字段),那么你将不得不在互斥量(++)和内存共享方面进行一些同步。

我会考虑使用AtomicLong和其他人,如果你可以,但你应该读共享内存和同步线程的一些教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

+0

我使用了Java Visual VM,并且我发现绝大多数线程花费大部分时间在Monitor(RED线)上的时间高达99% - 因此这是针对它们正在访问和修改的静态变量,并且必须等一下?我没有在任何地方使用'synchronized'。 [Image1](https://s3-us-west-2.amazonaws.com/vikesh-off/Threads.PNG) [Image2](https://s3-us-west-2.amazonaws.com /vikesh-off/Threads2.PNG) – ykesh

+0

无论何时读取或写入共享内存@ykesh,都需要进行某种同步。我在我的文章中添加了Java线程教程。 – Gray

+0

这意味着你可能有线程看不到这些共享变量的最新值。不知道这是否是您的性能问题。 – Gray