Java线程池为什么执行效率没有显示创建线程高呢

发布于 2022-09-11 18:33:01 字数 1016 浏览 32 评论 0

问题描述

同步二十万条数据,我想使用多线程同时进行, 但为什么我使用线程池同步数据的效率比我显示创建线程更慢呢?

这是显示创建线程:

    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();
    }
        

//这是使用线程池创建

    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();
    }

不应该是使用了线程池 效率更高更快吗,为什么反而显示创建线程保存到数据库更快呢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

把人绕傻吧 2022-09-18 18:33:01

很显然,线程池的代码有几个问题:

  1. exec 初始化的时候,线程池内部有多少线程?如果线程池内部线程本身比较少,循环时候,线程池也会通过 new Thread 线程的方式为线程池补充线程。
  2. 也是最重要的一点,for 循环中每次都 exec.shutdown(),调用该方法的意思是关闭当前线程池。线程池本身并不需要关闭。更不应该在 for 循环中关闭。
    /**
     * 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();
    }

查看 shutdown 源码,可以看到 shutdown 后,线程池不再接受新任务。
也就是第一次 for 循环,线程池增加了一个任务。然后调用 shutdown 后,线程池就不再接受新的任务了。
意思是说:线程池的代码其实只有一个线程在处理任务,而上面的 new Thread 代码却有多个线程在处理。
当然是上面的代码处理的快。

日暮斜阳 2022-09-18 18:33:01

首先你得保证你的测试代码是正确的。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文