我开始为 Java 中已经存在的项目(非多线程项目)开发一些多线程平台,我需要性能增益,从而减少整个项目中复杂计算的时间。
我一直在使用 Executors,但与 ThreadGroup 或纯 Runnable 相比,我真的不知道它是否是性能提升的最佳解决方案。
那么,应该使用哪一个呢?
我开始为 Java 中已经存在的项目(非多线程项目)开发一些多线程平台,我需要性能增益,从而减少整个项目中复杂计算的时间。
我一直在使用 Executors,但与 ThreadGroup 或纯 Runnable 相比,我真的不知道它是否是性能提升的最佳解决方案。
那么,应该使用哪一个呢?
如果您将线程池重用于多个计算,您只会从线程池中获得性能提升(即,您启动一个有 10 个线程的池并执行 10 个任务 100 次,而不是每次启动 10 个线程 100 次)。他们仍然需要初始开销来启动,你无法逃避这部分。所以这里有一个例子:
ExecutorService exec = Executors.newFixedThreadPool(10);
for(int i = 0; i < 10; i++) {
exec.submit(new Task(i));
}
// later
for(int i = 0; i < 10; i++) {
exec.submit(new Task(i));
}
exec.shutdown(); // etc.
在这种情况下,我只支付启动 10 个线程一次的开销,在开始时。
使用纯线程:
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i < 10; i++) {
Thread t = new Thread(new Task(i));
threads.add(t);
t.start();
}
for(Thread t: threads) {
t.join();
}
// later I need more work
threads = new ArrayList<Thread>();
for(int i = 0; i < 10; i++) {
Thread t = new Thread(new Task(i));
threads.add(t);
t.start();
}
for(Thread t: threads) {
t.join();
}
在这种情况下,我支付了两次启动 10 个线程的开销,这是对线程的不好使用。当然,如果你只需要执行一次这些任务,不会有任何性能差异,只是使用执行器更容易。
我不明白你所说的纯Runnable
(可能是纯线程?)的意思,因为线程池(执行程序)也适用于Runnable
s.
ThreadGroup
是一种组织线程的方式,很少使用。
Executors
采取“纯” Runnable
,所以我假设您的意思是Executors
与分叉自己的线程进行比较?这两种解决方案在性能增益方面是相似的,但这些ExecutorService
类非常易于使用。它们允许您提交一系列Runnable
并行执行的类,具体取决于您为池提供的线程数。
真正的诀窍是弄清楚将您的工作划分为可以并行执行的作业 - 在您分叉的线程中或通过线程池。
一个常见的代码模式Executors
:
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// submit my jobs which are classes that implement Runnable
for (MyRunnable myRunnable : myRunnables) {
threadPool.submit(myRunnable);
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();