Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么单线程java程序有这么多线程?_Java_Multithreading - Fatal编程技术网

为什么单线程java程序有这么多线程?

为什么单线程java程序有这么多线程?,java,multithreading,Java,Multithreading,我有一个java程序,它有13个线程,尽管其中只有一个线程的cpu使用率为99%,并且已经运行了约24小时。其他的cpu使用率为0.0%,显示的时间+介于0:00.0到0:12.82之间,其中一个为3:51.48。该程序旨在成为一个单线程程序,因此我想知道为什么会有其他线程 他们在做什么?为什么他们显示出如此少的cpu使用率和时间+ 更新:我有一个我写的旧java程序(第一个程序-不要评判我!),它是单线程的,并且显示了相同类型的线程使用 import java.io.*; class xdr

我有一个java程序,它有13个线程,尽管其中只有一个线程的cpu使用率为99%,并且已经运行了约24小时。其他的cpu使用率为0.0%,显示的
时间+
介于
0:00.0
0:12.82
之间,其中一个为
3:51.48
。该程序旨在成为一个单线程程序,因此我想知道为什么会有其他线程

他们在做什么?为什么他们显示出如此少的cpu使用率和时间+

更新:我有一个我写的旧java程序(第一个程序-不要评判我!),它是单线程的,并且显示了相同类型的线程使用

import java.io.*;

class xdriver {
  static int N = 100;
  static double pi = 3.141592653589793;
  static double one = 1.0;
  static double two = 2.0;

  public static void main(String[] args) {
    //System.out.println("Program has started successfully\n");

    if( args.length == 1) {
      // assume that args[0] is an integer
      N = Integer.parseInt(args[0]);
    }   

    // maybe we can get user input later on this ...
    int nr = N;
    int nt = N;
    int np = 2*N;

    double dr = 1.0/(double)(nr-1);
    double dt = pi/(double)(nt-1);
    double dp = (two*pi)/(double)(np-1);

    System.out.format("nn --> %d\n", nr*nt*np);

    if(nr*nt*np < 0) {
      System.out.format("ERROR: nr*nt*np = %d(long) which is %d(int)\n", (long)( (long)nr*(long)nt*(long)np), nr*nt*np);
      System.exit(1);
    }   

    // inserted to artificially blow up RAM
    double[][] dels = new double [nr*nt*np][3];

    double[] rs = new double[nr];
    double[] ts = new double[nt];
    double[] ps = new double[np];

    for(int ir = 0; ir < nr; ir++) {
      rs[ir] = dr*(double)(ir);
    }   
    for(int it = 0; it < nt; it++) {
      ts[it] = dt*(double)(it);
    }   
    for(int ip = 0; ip < np; ip++) {
      ps[ip] = dp*(double)(ip);
    }   

    double C = (4.0/3.0)*pi;
    C = one/C;

    double fint = 0.0;
    int ii = 0;
    for(int ir = 0; ir < nr; ir++) {
      double r = rs[ir];
      double r2dr = r*r*dr;
      for(int it = 0; it < nt; it++) {
        double t = ts[it];
        double sint = Math.sin(t);
        for(int ip = 0; ip < np; ip++) {
          fint += C*r2dr*sint*dt*dp;

          dels[ii][0] = dr; 
          dels[ii][1] = dt; 
          dels[ii][2] = dp; 
        }   
      }   
    }   

    System.out.format("N ........ %d\n", N); 
    System.out.format("fint ..... %15.10f\n", fint);
    System.out.format("err ...... %15.10f\n", Math.abs(1.0-fint));
  }
}
import java.io.*;
XD级河流{
静态int N=100;
静态双pi=3.141592653589793;
静态双1=1.0;
静态双二=2.0;
公共静态void main(字符串[]args){
//System.out.println(“程序已成功启动\n”);
如果(args.length==1){
//假设args[0]是一个整数
N=整数.parseInt(args[0]);
}   
//也许我们以后可以得到用户的输入。。。
int nr=N;
int nt=N;
int np=2*N;
双dr=1.0/(双)(nr-1);
双dt=pi/(双)(nt-1);
双dp=(两个*pi)/(两个)(np-1);
System.out.format(“nn-->%d\n”,nr*nt*np);
如果(nr*nt*np<0){
System.out.format(“错误:nr*nt*np=%d(长),即%d(int)\n”,(长)((长)nr*(长)nt*(长)np),nr*nt*np);
系统出口(1);
}   
//插入以人工爆破闸板
双精度[][]增量=新双精度[nr*nt*np][3];
双精度[]rs=新双精度[nr];
double[]ts=新的double[nt];
double[]ps=新的double[np];
对于(int-ir=0;ir
最有可能的线程是在某处创建的,从未使用过

例如:

ExecutorService es = Executors.newFixedThreadPool(12);
// burn cpu, using only one thread (main)
int i = 0;
while(true) {
    i++;
}

TIME+
from top是花费的CPU时间量。一种解释是,如果一个进程一直阻塞或只是一直阻塞,那么它将同时具有较低的CPU使用率和较低的
时间+

启动Java程序意味着启动JVM并告诉它运行哪个主类(通常有一个静态main方法)

除了上面提到的主线程之外,这个JVM还产生了几个后台线程

其中包括

  • 虚拟机线程:等待要求虚拟机处于安全点的任务的观察线程。例如,有一个垃圾收集任务完全“阻止世界”。但是还有其他的
  • GC线程:为运行垃圾收集而维护的多个线程
  • 编译线程:这些线程用于将字节码编译为本机机器码
可能还有更多

此外,如果您使用AWT或Swing,您将从这些框架中获得更多的线程。其中之一就是所谓的事件调度器thred(EDT)。当然,您可能创建并运行了一些线程:计时器、执行器,或者只是一些任意线程。即使是一个简单的hello world应用程序,也可能有十几个线程在运行

但是这些线程中的大多数都是等待而不是做一些事情。所以很有可能只有一个线程真正工作,从而利用了一些CPU


虽然。。。100%的CPU利用率可能是某个问题的指标。例如,一个永无止境的循环。你必须使用剖析器来找出真正发生的事情。但它可能只是一个具有如此CPU利用率的程序。您的判断。

引用已完成的讨论和其他研究

几个核心JVM线程:

  • 附加侦听器:这是一个始终侦听其他JVM线程以发送请求的线程。一个实际的例子是分析或生产级应用程序监控工具(如DynaTrace,我不打算这样做)
  • 信号调度器:当操作系统向JVM发出信号时,信号调度器线程将把信号传递给相应的处理程序
  • 引用处理程序:高优先级线程将挂起的引用排队。GC创建一个需要处理的引用的简单链表,该线程快速将它们添加到适当的队列中,并通知ReferenceQueue侦听器
  • 终结器:终结器线程调用终结器方法
  • DestroyJavaVM:此线程在程序退出时卸载Java VM。大多数时候,它应该等待
  • 垃圾收集器:负责Java垃圾收集机制的线程,具体取决于是否启用了GC
  • main:运行包含
    main
    方法的程序的主线程
  • 需要注意的一点是,它将取决于JVM实现,即它将启动多少个核心线程以及哪些核心线程,但即使Java程序被编写为单线程,JVM中也会有多个线程

    Java程序可以是单线程的,但JVM(将运行用户