java - 线程转储显示线程状态始终为 TIMED_WAITING

标签 java multithreading threadpoolexecutor jstack

我创建了一个使用 Executor 框架的程序。我创建了一个定期调度的单个线程。

这里是相同的完整源代码:

package com.example;
import java.security.SecureRandom;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExecutorFrameworkDemo {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExecutorFrameworkDemo.class);

    static {
        long refresh = 120000;
        long initialDelay = 120000;
        ScheduledExecutorService scheduledThreadPool = null;
        SecureRandom sr = new SecureRandom();
        scheduledThreadPool = Executors.newSingleThreadScheduledExecutor((Runnable run) -> {
        Thread t = Executors.defaultThreadFactory().newThread(run);
        t.setDaemon(true);
        t.setName("Demo-pool");
        t.setUncaughtExceptionHandler(
                (thread, e) -> LOGGER.error("Uncaught exception for Demo-pool thread " + thread.getName(), e));
        return t;
    });

    scheduledThreadPool.scheduleAtFixedRate(() -> {
        System.out.println("Executing thread " + Thread.currentThread().toString() + "at" + new Date());

    }, initialDelay + sr.nextInt((int) refresh / 4), refresh + sr.nextInt((int) refresh / 4),
            TimeUnit.MILLISECONDS);
    }
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Inside main thread");
        Thread.sleep(50000000);
        System.out.println("Inside main thread, after main's Sleep delay");
    }
}

它创建一个按固定时间表运行的单个线程;事实上,每 2 分钟 + 几秒后我确实看到了输出。

同时,我连续进行线程转储,希望在某个时间点线程状态为 RUNNABLE ,但是它总是给我 TIMED_WAITED .

下面是相同的实际线程转储:


"Demo-pool" #12 daemon prio=5 os_prio=31 tid=0x00007f96f3230000 nid=0x5603 waiting on condition [0x0000700007752000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007976182f0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748) 

我看不到 RUNNABLE 状态是偶然吗?

我正在使用 jstack 进行线程转储,使用 shell 脚本,无限循环,如下:

获取线程转储的脚本:

#!/bin/bash
itr=0
while true
  do
     (( ++itr ))
      jstack $1 > jstack_Iteration_${itr}
  done

其中,$1 是 java 进程的 PID,作为命令参数传递。

最佳答案

要看到线程处于 RUNNABLE 状态,意味着您在执行 System.out.println 的精确微秒内执行转储。这不太可能。对您的 Runnable 进行更耗时的实现,例如循环形式的繁忙等待:

for (int i = 0; i < 10000000; i++) {
    // do nothing
}

不要执行 Thread.sleepwait,否则您最终会处于 RUNNABLE 之外的其他状态。

关于java - 线程转储显示线程状态始终为 TIMED_WAITING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56925071/

相关文章:

java - 如何在quartz上下文中执行db/jpa操作?

java - 如何同步通知生成器和警报管理器?

Java 控制台日志未使用 Applet 写入磁盘

java - java中ThreadPoolExecutor的maximumPoolSize的作用是什么

java - 无法在 RejectionHandler 中获取 CallableThread

java - 构建器模式的使用

java - 为什么线程中的公共(public)方法无法在 onCreate 中解析?

multithreading - Clojure - 使用代理会大大减慢执行速度

c# - 线程有什么区别

python - IOLoop.current().run_in_executor() 和 ThreadPoolExecutor().submit() 的区别