Java多线程-空闲线程的状态


  1. 我是Java多线程的新手。想知道在ThreadPoolExecutor的情况下空闲线程的状态。它在可运行/等待中吗?

  2. 如果空闲线程处于RUNNABLE状态,新任务如何附加到空闲线程?我们给线程/池分配一个可运行/可调用的对象。但我的问题是ThreadPoolExecutor如何分配队列可运行对象到空闲线程??

这很容易发现:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.io.IOException;
public class ThreadExample {
public static void main(String[] args) throws IOException {
Executor executor = Executors.newFixedThreadPool(5);
// force the threads to be started
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
try {Thread.sleep(1000);} catch (InterruptedException e) {
}
});
}
// don't terminate
System.in.read();
}
}

运行:

$ javac ThreadExample.java
$ java ThreadExample

在另一个控制台中,等待任务完成至少一秒钟后:

$ ps
PID TTY           TIME CMD
3640 ttys000    0:00.25 -bash
5792 ttys000    0:00.15 java ThreadExample
5842 ttys001    0:00.05 -bash
$ jstack 5792
...
"pool-1-thread-1" #12 prio=5 os_prio=31 cpu=1.77ms elapsed=13.37s tid=0x00007fe99f833800 nid=0xa203 waiting on condition  [0x00007000094b2000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@11.0.2/Native Method)
- parking to wait for  <0x000000061ff9e998> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@11.0.2/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@11.0.2/AbstractQueuedSynchronizer.java:2081)
at java.util.concurrent.LinkedBlockingQueue.take(java.base@11.0.2/LinkedBlockingQueue.java:433)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.2/ThreadPoolExecutor.java:1054)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.2/ThreadPoolExecutor.java:1114)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.2/ThreadPoolExecutor.java:628)
at java.lang.Thread.run(java.base@11.0.2/Thread.java:834)
...

所有池线程都处于该状态。

  1. 想知道ThreadPoolExecutor情况下空闲线程的状态。它在可运行/等待中吗?

它将会等待。它正在等待(在Queue.take()调用中)一个新任务出现在工作队列中。在当前的实现中,这涉及到类似于wait/notify的机制。

你的第二个问题因此没有意义。

然而,值得注意的是:

  1. 没有"idle">

  2. 在当前的HotSpot jvm中,实际的调度(决定哪些线程获得优先级并为它们分配一个内核来运行)是由操作系统处理的。

  3. 在Loom JVM中(Loom仍然是一个孵化器项目),轻量级虚拟线程(" fiber ")由JVM而不是操作系统调度(到本地线程)。