线程转储始终显示线程状态 TIMED_WAITING
Thread dump show state of thread always TIMED_WAITING
我创建了一个使用 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-script 在无限循环中,如下所示:
获取线程转储的脚本:
#!/bin/bash
itr=0
while true
do
(( ++itr ))
jstack > jstack_Iteration_${itr}
done
其中,$1 是 java 进程的 PID,作为命令参数传递。
要查看 RUNNABLE 中的线程意味着,您在它执行 System.out.println
的精确微秒内执行转储。这不太可能。对 Runnable
进行更耗时的实施,例如循环形式的忙等待:
for (int i = 0; i < 10000000; i++) {
// do nothing
}
不要执行 Thread.sleep
或 wait
,否则你最终会进入不同于 RUNNABLE 的状态。
我创建了一个使用 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-script 在无限循环中,如下所示:
获取线程转储的脚本:
#!/bin/bash
itr=0
while true
do
(( ++itr ))
jstack > jstack_Iteration_${itr}
done
其中,$1 是 java 进程的 PID,作为命令参数传递。
要查看 RUNNABLE 中的线程意味着,您在它执行 System.out.println
的精确微秒内执行转储。这不太可能。对 Runnable
进行更耗时的实施,例如循环形式的忙等待:
for (int i = 0; i < 10000000; i++) {
// do nothing
}
不要执行 Thread.sleep
或 wait
,否则你最终会进入不同于 RUNNABLE 的状态。