其他人讨论了线程的成本来源。这个答案涵盖了为什么创建线程与许多操作相比并不那么昂贵,但是相对与任务执行替代方案相比,这是非常昂贵的相对更便宜。
在另一个线程中运行任务最明显的替代方法是在同一个线程中运行该任务。对于那些假设更多线程总是更好的人来说,这是很难理解的。逻辑是,如果将任务添加到另一个线程的开销大于您节省的时间,那么在当前线程中执行任务可能会更快。
另一种选择是使用线程池。线程池可以有两个更高的效率。1)重用已经创建的线程。2)您可以调优/控制线程数,以确保您具有最佳性能。
以下程序打印.。
Time for a task to complete in a new Thread 71.3 us
Time for a task to complete in a thread pool 0.39 us
Time for a task to complete in the same thread 0.08 us
Time for a task to complete in a new Thread 65.4 us
Time for a task to complete in a thread pool 0.37 us
Time for a task to complete in the same thread 0.08 us
Time for a task to complete in a new Thread 61.4 us
Time for a task to complete in a thread pool 0.38 us
Time for a task to complete in the same thread 0.08 us
这是对一个琐碎任务的测试,它公开了每个线程选项的开销。(这个测试任务实际上是在当前线程中执行的最好的任务。)final BlockingQueue queue = new LinkedBlockingQueue();Runnable task = new Runnable() {
@Override
public void run() {
queue.add(1);
}};for (int t = 0; t
{
long start = System.nanoTime();
int runs = 20000;
for (int i = 0; i
new Thread(task).start();
for (int i = 0; i
queue.take();
long time = System.nanoTime() - start;
System.out.printf("Time for a task to complete in a new Thread %.1f us%n", time / runs / 1000.0);
}
{
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService es = Executors.newFixedThreadPool(threads);
long start = System.nanoTime();
int runs = 200000;
for (int i = 0; i
es.execute(task);
for (int i = 0; i
queue.take();
long time = System.nanoTime() - start;
System.out.printf("Time for a task to complete in a thread pool %.2f us%n", time / runs / 1000.0);
es.shutdown();
}
{
long start = System.nanoTime();
int runs = 200000;
for (int i = 0; i
task.run();
for (int i = 0; i
queue.take();
long time = System.nanoTime() - start;
System.out.printf("Time for a task to complete in the same thread %.2f us%n", time / runs / 1000.0);
}}}
正如您所看到的,创建一个新线程只需花费70 s。这在许多(如果不是大多数的话)用例中可以被认为是微不足道的。相对而言,它比其他选项更昂贵,在某些情况下,线程池或根本不使用线程是一个更好的解决方案。