java - 当我只创建了两个线程时,为什么 `ps` 会列出 > 2 个 Java 线程/"light-weight processes"?

标签 java linux multithreading process

我有一个Java程序:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class App {

    static class Worker implements Runnable {

        public Worker() {}

        public void run() {
            while (true) {
                System.out.println("Sleeping");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(new Worker());
    }
}

该代码是使用 Maven 构建的,并使用 java -jar ... 执行。 .

如果我运行 ps -ef -o nlwp,pid,lwp,args | grep 3779 | grep -v grep要列出进程及其关联进程的数量,我得到:

15  3779  3779  \_ java -jar ./threadsim-1.0-SNAPSHOT.jar <snip>

我可以看到该进程有 15 个与之关联的轻量级进程(最左边的 header 是 nlwpps 格式,即轻量级进程的数量)。据我统计,应该有两个:主线程和我创建的“工作”线程。

谁能详细说明为什么报告为 15?

最佳答案

如果您运行jstack来查看每个线程的堆栈跟踪,您将得到有关这些线程正在做什么的提示:

$ jps -lvm

16321 com.intellij.rt.execution.application.AppMain App -Didea.launcher.port=7532 -Didea.launcher.bin.path=/opt/idea-IU-141.1192.2/bin -Dfile.encoding=UTF-8

$ jstack 16321
2015-06-11 15:15:49
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=0 tid=0x00007f4268001000 nid=0x4040 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x00007f42cc00a000 nid=0x3fc3 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"pool-1-thread-1" #11 prio=5 os_prio=0 tid=0x00007f42cc13a800 nid=0x3fe0 waiting on condition [0x00007f427c4fe000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at App$Worker.run(App.java:14)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x00007f42cc137800 nid=0x3fdf runnable [0x00007f429b101000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90)
    at java.lang.Thread.run(Thread.java:745)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f42cc0d2000 nid=0x3fdd runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f42cc0cd000 nid=0x3fdc waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f42cc0cb000 nid=0x3fdb waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f42cc0c9000 nid=0x3fda waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f42cc0c6000 nid=0x3fd9 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f42cc0c4800 nid=0x3fd8 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f42cc08c000 nid=0x3fd0 in Object.wait() [0x00007f42a0208000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000718b06f58> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x0000000718b06f58> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f42cc08a000 nid=0x3fcf in Object.wait() [0x00007f42a0309000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000718b06998> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
    - locked <0x0000000718b06998> (a java.lang.ref.Reference$Lock)

"VM Thread" os_prio=0 tid=0x00007f42cc085000 nid=0x3fce runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f42cc01f800 nid=0x3fc4 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f42cc021000 nid=0x3fc5 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f42cc023000 nid=0x3fc6 runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f42cc025000 nid=0x3fc7 runnable 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f42cc026800 nid=0x3fc8 runnable 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f42cc028800 nid=0x3fc9 runnable 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f42cc02a000 nid=0x3fca runnable 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f42cc02c000 nid=0x3fcb runnable 

"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x00007f42cc02e000 nid=0x3fcc runnable 

"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x00007f42cc02f800 nid=0x3fcd runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f42cc0d5000 nid=0x3fde waiting on condition 

JNI global references: 15

您可以看到有一个线程用于后台编译、GC、终结器/引用清理、监听 Ctrl-Break 以及其他一些内务处理工作。

关于java - 当我只创建了两个线程时,为什么 `ps` 会列出 > 2 个 Java 线程/"light-weight processes"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30783315/

相关文章:

c++ - boost 多部分进程的互斥量使用

java - 与 Bitmap.Config.ALPHA_8 的像素完美碰撞

linux - 如何为 Docker 容器提供更多资源

multithreading - 如何使用 CLI 工具确定 Wildfly 11 上哪些线程使用了大量 CPU?

linux - Puppet 分阶段重启

linux - cp 命令在 Linux 中失败

c++ - 进程内运行线程的名称

Java 获取像素区域并转换为图像 - 如何才能更有效?

java - NoClassDefFoundError + Appl

java - 无法让Java和C#通过socket进行通信