2014-03-25 240 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