Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a single threaded java program have so many threads?

I have a java program which has 13 threads, though only one of them is at 99% cpu usage and has been running for ~24 hours. The others are at 0.0% cpu usage and show a TIME+ of anywhere from 0:00.0 to 0:12.82 and one has 3:51.48. The program is intended to be a single threaded program, so I'm wondering why the other threads are there?

What are they doing and why do they show so little cpu usage and TIME+?

UPDATE: I have an old java program I wrote (first program - don't judge me!) which is single threaded and shows the same type of thread usage ...

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));
  }
}
like image 834
drjrm3 Avatar asked Jun 24 '15 14:06

drjrm3


3 Answers

Starting a Java program means starting a JVM and telling it which main class to run (that usually has a static main method).

This JVM spawns several background threads in addition to the above mentioned main thread.

Among them are

  • The VM thread: An observing thread that waits for tasks that require the VM to be at a safe point. For example, there is a garbage collection task that fully "stops the world". But there are others.
  • GC threads: Several threads that are maintained to run the garbage collection.
  • Compile threads: These threads are used to compile byte code into native machine code.

There might be many more.

Additionally, if you are using AWT or Swing, you will get some more threads from these frameworks. One of them is the so-called event dispatcher thred (EDT). And - of course - there might be thread that you did create and run: timers, executors, or simply some arbitrary threads. Even for a simple hello world application there might be a dozen of threads running.

But most of these threads are more waiting than doing something. So chances are high that only one thread is really working, thus utilizing some CPU.

Although ... 100% CPU utilization might be an indicator of some problem. A never-ending loop, for example. You have to use a profiler for finding out what really happens. But it could be simply a program that has such a CPU utilitation. Your judgement.

like image 121
Seelenvirtuose Avatar answered Oct 07 '22 07:10

Seelenvirtuose


Quoting the discussion done here and other research.

Few of core JVM threads:

  1. Attach Listener: This is thread which always listens for other JVM threads to send a request. A practical example is in case of profiling or (I am not about this though) production level application monitoring tools like DynaTrace.
  2. Signal Dispatcher: When the OS raises a signal to the JVM, the signal dispatcher thread will pass the signal to the appropriate handler.
  3. Reference Handler: High-priority thread to enqueue pending References. The GC creates a simple linked list of references which need to be processed and this thread quickly adds them to a proper queue and notifies ReferenceQueue listeners.
  4. Finalizer: The Finalizer thread calls finalizer methods.
  5. DestroyJavaVM: This thread unloads the Java VM on program exit. Most of the time it should be waiting.
  6. Garbage Collector: Thread responsible for Java's garbage collection mechanism, depending upon if GC is enabled or not.
  7. main: Main thread running your program containing main method.

One important point to note is that it will depend upon JVM implementations that how many and which all core threads it will start but even if Java program is written to be a single threaded, there would be more than one thread in JVM.

Java program can be single threaded but JVM (which will run user defined Java program) is multi-threaded and will have (at-least for latest JVMs) more than one thread even from start.

Below is a snapshot of my Java HotSpot(TM) Client VM version 24.55-b03, running a single threaded Java program:

To answer your query

What are they doing and why do they show so little cpu usage and TIME+?

What part: There are started for a purpose by JVM, as explained above like JVM wants to listen if any profiling or monitoring program wants to gets some details from JVM.
Why part: Because they are really not active or running, they are in wait or parked state (see the Yellow threads in my attached snapshot, if you have a GUI monitoring app then you should also see Yellow or else if command line then threads in WAIT state) and so they are not occupying any or least CPU cycles and hence less CPU usage. Again TIME+ will show you time for they have been active, and since they are not, this parameter is also less.

Hope this helps!

enter image description here

like image 37
hagrawal Avatar answered Oct 07 '22 08:10

hagrawal


Most likely threads have been created somewhere and are never used.

For instance:

ExecutorService es = Executors.newFixedThreadPool(12);
// burn cpu, using only one thread (main)
int i = 0;
while(true) {
    i++;
}
like image 28
Jean Logeart Avatar answered Oct 07 '22 07:10

Jean Logeart