为什么创建一个线程消耗会很高?

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

Java教程说,创建线程消耗很高。但为什么呢?

头像是我媳妇头像是我媳妇提问于
独孤求婚windy机器学习回答于

Java线程的创建成本很高,因为需要进行大量的工作:

  • 必须为线程堆栈分配和初始化大量内存块。
  • 需要进行系统调用,以便在主机OS中创建/注册本机线程。
  • 描述符需要创建、初始化并添加到JVM内部数据结构中。

从某种意义上说,线程绑定资源的代价也很高;例如,线程堆栈、从堆栈可以访问的任何对象、JVM线程描述符、OS本机线程描述符。

leosslyc回答于

在另一个线程中运行任务的最明显替代方法是在同一个线程中运行该任务。对于多线程神教的话的确很难理解。

另一种选择是使用线程池。线程池可以更有效率。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<Integer> queue = new LinkedBlockingQueue<Integer>();
Runnable task = new Runnable() {
    @Override
    public void run() {
        queue.add(1);
    }
};

for (int t = 0; t < 3; t++) {
    {
        long start = System.nanoTime();
        int runs = 20000;
        for (int i = 0; i < runs; i++)
            new Thread(task).start();
        for (int i = 0; i < runs; 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 < runs; i++)
            es.execute(task);
        for (int i = 0; i < runs; 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 < runs; i++)
            task.run();
        for (int i = 0; i < runs; 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);
    }
}
}

扫码关注云+社区