Why is creating a Thread said to be expensive?

前端 未结 6 1930
遇见更好的自我
遇见更好的自我 2020-11-22 09:34

The Java tutorials say that creating a Thread is expensive. But why exactly is it expensive? What exactly is happening when a Java Thread is created that makes its creation

6条回答
  •  遇见更好的自我
    2020-11-22 10:20

    Others have discussed where the costs of threading come from. This answer covers why creating a thread is not that expensive compared to many operations, but relatively expensive compared to task execution alternatives, which are relatively less expensive.

    The most obvious alternative to running a task in another thread is to run the task in the same thread. This is difficult to grasp for those assuming that more threads are always better. The logic is that if the overhead of adding the task to another thread is greater than the time you save, it can be faster to perform the task in the current thread.

    Another alternative is to use a thread pool. A thread pool can be more efficient for two reasons. 1) it reuses threads already created. 2) you can tune/control the number of threads to ensure you have optimal performance.

    The following program prints....

    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
    

    This is a test for a trivial task which exposes the overhead of each threading option. (This test task is the sort of task that is actually best performed in the current thread.)

    final BlockingQueue queue = new LinkedBlockingQueue();
    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);
        }
    }
    }
    

    As you can see, creating a new thread only costs ~70 µs. This could be considered trivial in many, if not most, use cases. Relatively speaking it is more expensive than the alternatives and for some situations a thread pool or not using threads at all is a better solution.

提交回复
热议问题