undefinedfix
Sign in

Why is the execution efficiency of java thread pool not as high as that of creating thread

respect99 edited in Wed, 13 Jul 2022

Problem description

To synchronize 200000 pieces of data, I want to use multithreading at the same time, but why is the efficiency of using thread pool to synchronize data slower than that of creating thread?

This is the display creation thread:

    for (int i = 0; i < studentIdList.size(); i++) {
      List<String> studentIds = studentIdList.get(i);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (String per : studentIds) {
                      //数据库操作
                }
            }
        }, "线程" + i);
        thread.start();
    }
        

//This is created using a thread pool

    ExecutorService exec= Executors.newCachedThreadPool();
    for (int i = 0; i < studentIdList.size(); i++) {
        List<String> studentIds = studentIdList.get(i);
        exec.execute(new Runnable() {
            @Override
            public void run() {
                for (String per : studentIds) {
                 //数据库操作
                }
            }
        });
        exec.shutdown();
    }

Shouldn't it be more efficient and faster to use the thread pool? Why is it faster to save the created thread to the database instead

2 Replies
Nahuel
commented on Thu, 14 Jul 2022

First of all, you have to make sure that your test code is correct...

lagalas
commented on Thu, 14 Jul 2022

Obviously, there are several problems with thread pool code:

  1. How many threads are there in the thread pool when exec is initialized? If there are few threads in the thread pool itself, the thread pool will also supplement threads for the thread pool through new thread thread.
  2. And most importantly, every time in the for loop exec.shutdown (), which means to close the current thread pool. The thread pool itself does not need to be shut down. It should not be closed in the for loop.
    /**
     * Initiates an orderly shutdown in which previously submitted
     * tasks are executed, but no new tasks will be accepted.
     * Invocation has no additional effect if already shut down.
     *
     * <p>This method does not wait for previously submitted tasks to
     * complete execution.  Use {@link #awaitTermination awaitTermination}
     * to do that.
     *
     * @throws SecurityException {@inheritDoc}
     */
    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

Looking at the source code of shutdown, you can see that after shutdown, the thread pool no longer accepts new tasks. That is, for the first time, a task is added to the thread pool. After calling shutdown, the thread pool no longer accepts new tasks. In fact, only one thread in the thread pool code is processing tasks, while the new thread code above has multiple threads. Of course, the above code is fast.