我已经将我的应用程序从一个单线程切换到一个多线程例程。
这在JUnit测试中非常好。当使用10线程运行它时,测试需要195 ms来完成,当只使用一个线程运行它时,应用程序需要406 ms来完成。因此,显然有一个性能优势。
但是,当它在服务器上运行时,应用程序现在所需的时间要比只有单线程时长得多。
基本上,我的应用程序读取csv文件中的一行,将它的一个值放在一个集合中,并将该行打印到另一个文件中。JUnit测试中输入文件的大小是关于35行长的,服务器上的输入文件大小是6 000 000行长的。
放置这些值的集合是一个同步的HashSet,它可以包含Long对象。
我正在使用Java VisualVM监视我的应用程序,但不幸的是,我不知道该寻找什么。
你对我如何解决这场表演危机有什么建议吗?
P.S.:大多数时候,我的线程被标记为等待,但我不知道它们是否真的在等待,或者它们是否太快,以致于Java VisualVM无法显示它。
为了进一步澄清我的例程:我读取了单线程文件,但是一旦读取了行,我就将结果对象传递给一个Runnable,该对象将其放入一个集合并打印到另一个文件中。同时,读取下一行并将其传递给其他线程。
正如我在日志文件中所看到的那样,线程正在做一些事情,而不仅仅是等待。但也有某些跳跃,比100毫秒更长的时间,在那里什么都没有发生。
其中一次跳跃:
2011-04-08 12:27:16,580 DEBUG [Thread-10] runnables.Runner - 7070927
2011-04-08 12:27:16,580 DEBUG [Thread-10] runnables.Runner - 9058759
2011-04-08 12:27:16,580 DEBUG [Thread-10] runnables.Runner - 7030928
2011-04-08 12:27:16,580 DEBUG [Thread-10] runnables.Runner - 15301035
2011-04-08 12:27:16,684 DEBUG [Thread-10] runnables.Runner - 7700929
2011-04-08 12:27:16,684 DEBUG [Thread-10] runnables.Runner - 17116545
2011-04-08 12:27:16,685 DEBUG [Thread-10] runnables.Runner - 4933581
2011-04-08 12:27:16,685 DEBUG [Thread-10] runnables.Runner - 2861116注:当时没有发生GC。
正如在下面的注释中所写的:我正在使用线程池。我的线程正在为同一个输出文件而斗争。它们都写入synchronized方法。
即使我把我的踏面池缩小到一个,表现还是很糟糕的。与以前的实现相比没有什么。这难道不排除IO依赖或线程切换之类的东西吗?
我现在已经修改了我的代码,以便在Runnable中几乎什么都不做。没有Set,没有写作。只有一条日志语句。但我还是得到了那些jumps。因此,我排除了一些人提出的写作或Set问题。当只运行一个线程时,我也得到了这些空闲时间。因此,线程滑动似乎也不是问题所在。
发布于 2011-04-08 13:27:12
我不知道具体的问题是什么,但它似乎是由Executor接口的一个糟糕的实现引起的。
我现在用
ExecutorService executor = Executors.newFixedThreadPool(nThreads);一切都很好。
17.12 min 10线程例程:13.45 min我发现了坏的代码:
Thread.sleep(100);在线程队列已满时调用。
发布于 2011-04-08 11:23:22
您的测试文件非常小,因此它很可能被整个I/O堆栈中的任何预读层完全读取。这使得整个执行CPU绑定。有了更多的线程,就可以使用更多的CPU并使其完成得更快。
真正的文件OTOH要长得多,所以问题变成了IO绑定。CPU大部分时间都在等待读取数据。在单个线程上,没有争用,IO可能更线性;而多线程版本更有可能生成大量的磁盘查找(到目前为止,在硬件上所能做的最慢的操作)
根据经验,如果您从磁盘或网络读取数据,并且不对其进行大量处理,则最好采用单线程处理。
发布于 2011-04-08 11:30:01
您所指的“跳转”是线程之间的切换时间。由于总的执行时间是有限的,一个线程的执行时间就会变得越小,您拥有的线程就越多。如果您必须执行多个线程,那么您的调度程序最终会切换线程,而没有线程会执行任何工作。从一个线程切换到另一个线程需要一定的固定时间。如果您的线程不使用多个内核,并且执行完全相同的操作,那么当比较多线程和单线程时,您的速度会更快。
https://stackoverflow.com/questions/5594227
复制相似问题