Почему однопоточная java-программа имеет так много потоков?

у меня есть программа java, которая имеет 13 потоков, хотя только один из них находится на 99% cpu и работает в течение ~24 часов. Другие находятся на 0.0% cpu usage и показывают TIME+ от 0:00.0 to 0:12.82 и 3:51.48. Программа предназначена для однопоточной программы, поэтому мне интересно, почему другие темы есть?

что они делают и почему они показывают так мало ЦП и времени+?

UPDATE: у меня есть старая программа java I написал (первая программа - не судите меня!), который является однопоточным и показывает тот же тип использования резьбы ...

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 successfullyn");

    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 --> %dn", 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 ........ %dn", N); 
    System.out.format("fint ..... %15.10fn", fint);
    System.out.format("err ...... %15.10fn", Math.abs(1.0-fint));
  }
}

4 ответов


цитирование обсуждения сделано здесь и другие исследования.

несколько основных потоков JVM:

  1. Прикрепить Слушатель: это поток, который всегда слушает другие потоки JVM для отправки запроса. Практический пример - это профилирование или (я не об этом) инструменты мониторинга приложений производственного уровня, такие как DynaTrace.
  2. Сигнал Диспетчеру: когда ОС поднимает сигнал на JVM, поток диспетчера сигналов передаст сигнал соответствующему обработчику.
  3. Укротитель Ссылок: высокоприоритетный поток для запросов ожидающих ссылок. GC создает простой связанный список ссылок, которые необходимо обработать, и этот поток быстро добавляет их в соответствующую очередь и уведомляет слушателей ReferenceQueue.
  4. финализатор: поток финализатора вызывает методы финализатора.
  5. DestroyJavaVM: этот поток выгружает Java VM при выходе из программы. Большую часть времени он должен ждать.
  6. Сборщик Мусора: поток, ответственный за механизм сбора мусора Java, в зависимости от того, включен ли GC или нет.
  7. main: основной поток, выполняющий вашу программу, содержащую main метод.

один важное замечание это будет зависеть от реализаций JVM, что сколько и какие все основные потоки он начнет, но даже если программа Java написана как однопоточная, в JVM будет более одного потока.

Java-программа может быть однопоточной, но JVM (которая будет запускать пользовательскую Java-программу) многопоточна и будет иметь (по крайней мере, для последних JVMs) более одного потока даже с самого начала.

Ниже приведен снимок моей Java HotSpot(TM) клиент VM версии 24.55-b03, работает однопоточная программа Java:

в ответить на ваш запрос

что они делают и почему они показывают так мало ЦП и Время+?

что входит: там запущены с целью JVM, как описано выше, как JVM хочет слушать, если какая-либо программа профилирования или мониторинга хочет получить некоторые детали от JVM.
почему часть: поскольку они действительно не активны или работают, они находятся в состоянии ожидания или припаркованы (см. желтые потоки в моем приложении снимок, если у вас есть приложение для мониторинга GUI, вы также должны увидеть желтый или еще если командная строка затем потоки в состоянии ожидания), и поэтому они не занимают каких-либо или наименьших циклов процессора и, следовательно, меньше использования процессора. Опять TIME+ покажет вам время, когда они были активны, и поскольку они не являются, этот параметр также меньше.

надеюсь, что это помогает!

enter image description here


запуск Java-программы означает запуск JVM и указание ему, какой основной класс запускать (который обычно имеет статический основной метод).

этот JVM порождает несколько фоновых потоков в дополнение к вышеупомянутому основному потоку.

среди них:

  • поток виртуальной машины: поток наблюдения, который ожидает задач, требующих, чтобы виртуальная машина находилась в безопасной точке. Например, существует задача сбора мусора, которая полностью "останавливает мир". Но есть и другие.
  • потоки GC: несколько потоков, которые поддерживаются для запуска сборки мусора.
  • компилировать темы: эти потоки используются для компиляции байт-кода в машинный код.

может быть еще много.

кроме того, если вы используете AWT или Swing, вы получите еще несколько потоков из этих фреймворков. Одним из них является так называемый event dispatcher thred (EDT). И - конечно - может быть поток, который вы создали и запустили: таймеры, исполнители или просто некоторые произвольные потоки. Даже для простого приложения hello world может быть запущена дюжина потоков.

но большинство этих потоков больше ждут, чем что-то делают. Так что шансы высоки, что только один поток действительно работает, таким образом, используя некоторый процессор.

хотя ... 100% загрузка ЦП может быть показателем некоторой проблемы. Например, бесконечная петля. Вы должны использовать профилировщик для выяснения того, что на самом деле происходит. Но это может быть просто программа, которая имеет такой utilitation процессора. Ваше суждение.


скорее всего, темы были созданы где-то и никогда не используются.

например:

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

TIME+ сверху - это количество затраченного времени процессора. Одно из объяснений - если процесс постоянно блокируется или просто всегда блокируется, чем он будет иметь как низкое использование процессора, так и низкое TIME+.