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

Posted

技术标签:

【中文标题】Java 多线程 - 空闲线程的状态【英文标题】:Java Multithreading - State of an Idle thread 【发布时间】:2021-10-15 08:01:14 【问题描述】:

    我是 Java 多线程的新手。想知道 ThreadPoolExecutor 的空闲线程的状态。是否处于 RUNNABLE/WAITING 状态?

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

【问题讨论】:

你可以在这里找到一个实现hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/… 感谢@AlbertoSinigaglia。这有帮助 【参考方案1】:

很容易找到:

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)
...

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

【讨论】:

根据ThreadExecutorService.java,所有空闲线程都处于Runnable状态。上面建议的代码显示等待,因为当前线程正在休眠。 runState 提供主要的生命周期控制,取值:RUNNING SHUTDOWN STOP TIDYING TERMINATED ThreadExecutorService 是什么,主线程的状态如何影响其他线程?不要将RUNNING 的执行者的runState 与线程的状态混淆。【参考方案2】:
    想知道在 ThreadPoolExecutor 的情况下空闲线程的状态。是否处于 RUNNABLE/WAITING 状态?

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

因此,您的第二个问题没有实际意义。

但是,值得注意的是:

    永远不会有“空闲”线程可以运行。

    在当前一代的 HotSpot JVM 中,实际的调度(决定哪些线程获得优先级并分配它们运行的​​核心)由操作系统处理。

    在 Loom JVM 中(Loom 仍然是一个孵化器项目),轻量级 virtual threads(“纤维”)由 JVM 而非操作系统调度(到本机线程)。

【讨论】:

以上是关于Java 多线程 - 空闲线程的状态的主要内容,如果未能解决你的问题,请参考以下文章

Pexpect 多线程空闲状态

JAVA多线程之AQS

JAVA多线程基础

java多线程--线程池的使用

Java基础学习——多线程之线程池

Java多线程:BlockingQueue实现生产者消费者模型