ThreadPool 中的 Runnable 与线程内和 ThreadPool 中的 Runnable 之间有什么区别

What is Difference between Runnable in a ThreadPool vs Runnable inside a Thread and in a ThreadPool

这有什么区别?请参考选项 1 和选项 2。因为我遇到了麻烦,因为它们好像是一样的。他们运行正确

Thread

ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);

        Thread callLogsThread = new Thread(new CallLogsRunnable());
        Thread contactsThread = new Thread(new ContactsRunnable());

        /*option 1**/
        executor.submit(new ContactsRunnable());
        executor.submit(new CallLogsRunnable());

        /*option 2**/
        executor.submit(contactsThread);
        executor.submit(callLogsThread);

        /*option 3**/
        contactsThread.start();
        contactsThread.join();
        callLogsThread.start();
        callLogsThread.join();

        executor.shutdown();

更新: 我添加了选项 3。选项 1 和选项 3 之间现在有什么区别。因为我知道选项 2 是废话。谢谢

从功能/行为的角度来看,没有区别。在 Thread 对象上调用 run() 将调用作为构造函数参数传递的 Runnable;请参阅 javadoc 以获得 Thread::run()

从效率的角度来看,第二个选项会创建不必要的 Thread 对象。这会降低性能,增加内存利用率并增加 GC 负载。

(效率影响会很小,但由于 Thread 对象没有实现任何目标......就不要这样做。)

从可读性/可维护性的角度来看,第二个选项将导致 "what the heck" 任何有经验的 Java 程序员阅读您的代码的反应。你不想要那个。弄清楚 "odd" 代码在做什么会浪费人们的时间。


您添加了第三个选项,其中 start() 个线程而不是使用线程池中的现有线程。

它比选项 1 和 2 都差。您现在不使用线程池,而是为每个任务启动一个新线程。那就是效率低得多。线程启动和退出的开销以数千个时钟周期来衡量...

如评论所述,选项 2) 仅有效,因为 Thread 实现了 Runnable,其中 run 方法是线程应该执行的操作。

如果您将 Thread 传递给执行程序,它将调用 Threads run() 方法 - 但实际的 Thread 本身不会有任何好处。所以选项2)是错误的。

如果你想在一个线程中启动 Runnable 直接使用 callLogsThread.start() - 然后不要忘记在线程完成时 join() 它。