【发布时间】:2018-03-23 05:33:23
【问题描述】:
我知道无法重新启动 java 线程。那么当我向newSingleThreadExecutor提交多个任务时,它是如何使用单线程执行所有任务的呢?
我的理解是 newSingleThreadExecutor 一次最多使用一个线程来处理任何提交的任务。我猜对 newFixedThreadPool 也是如此。 如果一个线程不能重新启动,那么为了执行 n 个任务,应该产生 n 个线程。我认为 newSingleThreadExecutor, newFixedThreadPool 将确保不会同时产生很多线程,就像我们不使用 ExecutorService 一样(我们将每个任务附加到一个线程并单独启动)
这里是代码示例
class Task implements Runnable {
public void run() {
System.out.println("ThreadID-" + Thread.currentThread().getId());
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
}
}
}
public class SingleThreadExecutorTest {
public static void main(String[] args) {
System.out.println("ThreadID-" + Thread.currentThread().getId());
ExecutorService ex = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
ex.execute(new Task());
}
}
}
上面的代码总是打印相同的 ThreadID。
如果我替换下面的行
Executors.newSingleThreadExecutor();
与
ExecutorService ex = Executors.newFixedThreadPool(2);
然后它再次能够使用 2 个线程执行所有任务。
仅当我使用时
Executors.newCachedThreadPool();
我看到不同的线程 ID。
ExecutorService 如何重用一个线程? 不让它到达死态吗?
【问题讨论】:
-
执行器将任务发送到池中,无限循环中的线程检查池中是否有要执行的新任务
-
所以 newSingleThreadExecutor 将有一个线程,其中 run 方法将运行一个无限循环。提交的 Runnable 对象将进入队列。无限循环将检查队列,轮询 Runnable 对象并调用它的 run 方法。所以这里的Runnable只是用来定义任务。我认为它会使用 Thread(Runnable) 构造函数创建一个 Thread 对象,这很糟糕。
标签: java multithreading