简单的Java示例运行14个线程。为什么?

简单的Java示例运行14个线程。为什么?,java,multithreading,Java,Multithreading,以下是简单的Java代码: public class Main { public static void main(String[] args) throws InterruptedException { System.out.println("Start"); Thread.sleep(5000); System.out.println("Done"); } } 使用14个线程运行。我知道有一些GC线程在后台运行,但是其他线程是

以下是简单的Java代码:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Start");
        Thread.sleep(5000);
        System.out.println("Done");
    }
}

使用14个线程运行。我知道有一些GC线程在后台运行,但是其他线程是用来做什么的呢?为什么有这么多的线程?我使用的是GentooLinux和Java1.6.0_26。使用Eclipse的编译器或javac编译并没有什么区别(在Eclipse中以调试模式运行它会增加3个线程,但这可能是合理的)。

我使用
jvisualvm
制作了这个屏幕截图。正在运行的线程(在eclipse中):

运行与*.jar文件相同的程序;只有4个守护进程线程和1个活动线程在运行。

默认情况下,我的JVM(1.6.0_26)会生成更多线程。大多数都有很好的描述性名称,暗示了它们的用途:

"Attach Listener" daemon prio=10 tid=0x0000000041426800 nid=0x2fb9 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Low Memory Detector" daemon prio=10 tid=0x00007f512c07e800 nid=0x2fa3 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007f512c07b800 nid=0x2fa2 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007f512c078800 nid=0x2fa1 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007f512c076800 nid=0x2fa0 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007f512c05a000 nid=0x2f9f in Object.wait() [0x00007f512b8f7000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007c14b1300> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0x00000007c14b1300> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x00007f512c058000 nid=0x2f9e in Object.wait() [0x00007f512b9f8000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007c14b11d8> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0x00000007c14b11d8> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x0000000041401800 nid=0x2f94 waiting on condition [0x00007f5135735000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at Main.main(Main.java:5)

"VM Thread" prio=10 tid=0x00007f512c051800 nid=0x2f9d runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x0000000041414800 nid=0x2f95 runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f512c001000 nid=0x2f96 runnable 

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f512c002800 nid=0x2f97 runnable 

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f512c004800 nid=0x2f98 runnable 

"GC task thread#4 (ParallelGC)" prio=10 tid=0x00007f512c006800 nid=0x2f99 runnable 

"GC task thread#5 (ParallelGC)" prio=10 tid=0x00007f512c008000 nid=0x2f9a runnable 

"GC task thread#6 (ParallelGC)" prio=10 tid=0x00007f512c00a000 nid=0x2f9b runnable 

"GC task thread#7 (ParallelGC)" prio=10 tid=0x00007f512c00c000 nid=0x2f9c runnable 

"VM Periodic Task Thread" prio=10 tid=0x00007f512c089000 nid=0x2fa4 waiting on condition 
“附加侦听器”守护程序prio=10 tid=0x0000000041426800 nid=0x2ff9等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“低内存检测器”守护程序prio=10 tid=0x00007f512c07e800 nid=0x2fa3可运行[0x0000000000000000]
java.lang.Thread.State:可运行
“C2编译器线程1”守护程序prio=10 tid=0x00007f512c07b800 nid=0x2fa2等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“C2编译器线程0”守护进程prio=10 tid=0x00007f512c078800 nid=0x2fa1等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“信号调度器”守护程序prio=10 tid=0x00007f512c076800 nid=0x2fa0 runnable[0x0000000000000000]
java.lang.Thread.State:可运行
对象中的“终结器”守护程序prio=10 tid=0x00007f512c05a000 nid=0x2f9f。等待()[0x00007f512b8f7000]
java.lang.Thread.State:正在等待(在对象监视器上)
在java.lang.Object.wait(本机方法)
-等待(java.lang.ref.ReferenceQueue$Lock)
位于java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
-锁定(java.lang.ref.ReferenceQueue$Lock)
位于java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
位于java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
对象中的“引用处理程序”守护程序prio=10 tid=0x00007F512C05800NID=0x2f9e。等待()[0x00007f512b9f8000]
java.lang.Thread.State:正在等待(在对象监视器上)
在java.lang.Object.wait(本机方法)
-等待(java.lang.ref.Reference$Lock)
等待(Object.java:485)
在java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
-锁定(一个java.lang.ref.Reference$Lock)
“主”优先级=10 tid=0x0000000041401800 nid=0x2f94等待条件[0x00007f5135735000]
java.lang.Thread.State:定时等待(休眠)
位于java.lang.Thread.sleep(本机方法)
Main.Main(Main.java:5)
“VM线程”优先级=10 tid=0x00007f512c051800 nid=0x2f9d可运行
“GC任务线程#0(并行GC)”优先级=10 tid=0x0000000041414800 nid=0x2f95可运行
“GC任务线程#1(并行GC)”优先级=10 tid=0x00007F512C01000 nid=0x2f96可运行
“GC任务线程#2(并行GC)”优先级=10 tid=0x00007f512c002800 nid=0x2f97可运行
“GC任务线程#3(并行GC)”优先级=10 tid=0x00007f512c004800 nid=0x2f98可运行
“GC任务线程4(并行GC)”优先级=10 tid=0x00007f512c006800 nid=0x2f99可运行
“GC任务线程#5(并行GC)”优先级=10 tid=0x00007F512C08000 nid=0x2f9a可运行
“GC任务线程#6(并行GC)”优先级=10 tid=0x00007f512c00a000 nid=0x2f9b可运行
“GC任务线程#7(并行GC)”prio=10 tid=0x00007f512c0c000 nid=0x2f9c runnable
“VM定期任务线程”优先级=10 tid=0x00007f512c089000 nid=0x2fa4等待状态
显然,大多数线程都与内存处理有关:有8个垃圾收集器线程,加上低内存检测器<代码>终结器和
引用处理程序
听起来好像它们也参与了内存管理

C2编译器线程0/1
几乎肯定与即时编译有关

VM定期任务线程
解释如下:


至于其余线程的确切用途,我不确定。

这可能无法回答问题,但至少有助于理解发生了什么。要获得线程的准确示例,请在应用程序中获取列表表单。(而不是从调试工具中。)

JVM w/o检测

  • 线程:主线程
  • 线程:引用处理程序
  • 线程:信号调度器
  • 线程:附加侦听器
  • 线程:终结器
JVM带检测(jconsole)

  • 线程:主线程
  • 线程:JMX服务器连接超时12
  • 线程:RMI TCP连接(1)-10.1.100.40
  • 线程:RMI TCP连接(2)-10.1.100.40
  • 线程:终结器
  • 线程:引用处理程序
  • 线程:RMI计划程序(0)
  • 线程:信号调度器
  • 线程:RMI TCP Accept-0
  • 线程:附加侦听器

实验

  • 执行以下代码
  • 启动jconsole并连接到该jvm
  • 公共类JVM{
    公共静态void main(字符串…参数)抛出InterruptedException{
    对于(java.util.Enumeration e=System.getProperties().propertyNames();e.hasMoreElements();){
    字符串prp=(字符串)e.nextElement();
    if(prp.startsWith(“java.vm”)| | prp.startsWith(“os”)){
    System.out.format(“[%s]=%s%n”,prp,System.getProperty(prp));
    }
    }
    java.text.DateFormat df=new java.text.simpleDataFormat(“HH:mm:ss.SSS”);
    对于(;;){
    System.out.format(“%s正在采样当前线程…%n”,df.format(new java.util.Date());
    java.util.Map stacks=Thread.getAllStackTraces();
    System.out.format(“>线程数:%d%n”,stacks.size());
    for(java.util.Map.Entry:stacks.entrySet()){
    Thread Thread=entry.getKey();
    StackTraceElement[]stack=entry.getValue();
    System.out.format(“>线程:%s%n”,Thread.getName());
    //Throwable t=新的Throwable(“Thread:+Thread.getName());
    //t.跟踪(堆栈);
    //t.printStackTrace(系统输出);
    }
    java.util.concurrent.TimeUni