java - 线程池重用线程

标签 java multithreading threadpool java.util.concurrent threadpoolexecutor

我知道这个话题已经被问了很多,但我不确定一个细节。 现在,线程池不会让线程在完成任务后死亡,并在以后根据需要重用它(正如所说的 herehere 等) 但是假设我的可运行对象在构造函数中有变量 -

MyRunnable(int a){
  this.a = a; 
}

然后,当我们尝试使用 Executors.newFixedThreadPool (或类似的东西)运行 Runnable 时,我们会说

executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool

现在,如果变量“a”在每次执行中都不同,那么线程池以后真的可以重用它吗? 我无法真正理解这是如何工作的,但我从未见过“线程池重用线程,除了......”,因此感到困惑。

最佳答案

不,您提交的Runnable以及与其相关的变量都不会被重用。

我认为你误解了ThreadRunnable,它们是不同的东西。 Runnable 只是普通对象,除了当您使用它创建新线程时将执行它的 run 方法。您可以查看this question

线程的复用并不意味着Runnable的复用,而是线程不断执行不同的Runnable

<小时/>

当您使用Runnable创建一个Thread,并像这样启动这个线程时:

new Thread(new Runnable()).start()

这个Runnalerun()方法会被执行,当run()退出后,这个Thread 也会终止。

但是,您提交给 ThreadPoolExecutorRunnbale 并不是上面代码中用于构造线程的那个。

<小时/>

简单来说,ThreadPoolExecutor 中的线程是这样创建的:

Runnable worker = new Runnable() {

    @Override
    public void run() {
        Runnable firstTask = getFirstTask();  // the first runnable 
        firstTask.run();

        Runnable queuedTask;
        while ( (queuedTask = getTaskFromQueue()) != null) {  // This could get blocked 
            queuedTask.run();
        }
    }
};
new Thread(worker).start();

注意,用于启动线程的Runnable不是您提交到池中的那个。

<小时/>

当您提交新的Runnable时,线程池将检查是否需要创建新线程(基于corePoolSize等参数)。

  • 如果有必要,它会创建一个新的Worker,并将此Runnable作为FirstTask,并使用此创建一个新线程>Worker 并启动它。
  • 如果没有,则会将 Runnbale 放入队列中。当有空闲线程时,它们会检查该队列并从中获取任务。

关于java - 线程池重用线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49964436/

相关文章:

java - 如何让我的简单 Java Web 服务正常工作?

java - 如何拥有一个可扩展的CardView?

java - 如何在旋转时保持应用程序的相同状态?

c# - 在C#中杀死TCP服务器的TCP客户端线程

multithreading - 事件驱动和基于线程的服务器系统有什么区别?

multithreading - 使用 Future.successful 和 Future.failed 是否从执行上下文管理的线程池中请求线程

java - 如何使 JFrame 变得无形?

c - 如何在不使用互斥量、futex 和信号量的情况下实现 "locking"机制?

c++ - POSIX pthread 多次使用同一个线程

c# - 多线程可显着提高内存和CPU的使用率