ホームページ  >  記事  >  Java  >  Java のデーモン スレッドとユーザー スレッドの詳細な紹介

Java のデーモン スレッドとユーザー スレッドの詳細な紹介

黄舟
黄舟オリジナル
2017-09-30 09:47:261744ブラウズ

この記事は主に Java のデーモン スレッドとユーザー スレッドについて簡単に説明したもので、非常に優れていると編集者が判断したので、参考として共有します。エディターに従って見てみましょう。

Java スレッドは、デーモン スレッド (デーモン スレッド) とユーザー スレッド (ユーザー スレッド) の 2 つのカテゴリに分けられます。JVM が起動すると、メイン関数が呼び出されます。関数はユーザー スレッドです。実際、ガベージ コレクション スレッドなどの多くのデーモン スレッドも JVM 内で開始されます。では、デーモン スレッドとユーザー スレッドの違いは何でしょうか?違いの 1 つは、デーモン以外の最後のスレッドが終了すると、現在デーモン スレッドが存在するかどうかに関係なく、JVM が通常どおり終了することです。つまり、デーモン スレッドが終了しても JVM の終了には影響しません。つまり、1 つのユーザー スレッドが終了しない限り、通常の状況では JVM は終了しないということです。

では、Java でデーモン スレッドを作成するにはどうすればよいでしょうか? コードは次のとおりです:


public static void main(String[] args) {

    Thread daemonThread = new Thread(new Runnable() {
      public void run() {
        
      }
    });
    
    //设置为守护线程
    daemonThread.setDaemon(true);
    daemonThread.start();
    
  }

スレッドのデーモン パラメータを true に設定するだけであることがわかります。

以下は、ユーザー スレッドとデーモン スレッドの違いをより深く理解するための例です。まず、次のコードを見てください:


public static void main(String[] args) {

    Thread thread = new Thread(new Runnable() {
      public void run() {
        for(;;){}
      }
    });
    
    //启动子线
    thread.start();
    
    System.out.print("main thread is over");
  }

結果の出力は次のとおりです:


上記のコードは以下を作成します。メインスレッドにスレッドスレッドが存在します。コードの実行結果から、メインスレッドが終了したことがわかります。 IDE からの出力の右側にある赤い四角形は、JVM プロセスが終了していないことを示しており、Mac で ps -eaf grep java を実行すると結果が出力されます。これもこの結論を証明します。

この結果は、親スレッドが終了しても、子スレッドはまだ存在し続けることができる、つまり、子スレッドのライフサイクルは親スレッドの影響を受けないことを示しています。また、ユーザー スレッドがまだ存在する場合、JVM プロセスは終了しないことも示しています。次に、上記のスレッド thread をデーモン スレッドとして設定し、実行してどのような効果があるかを確認します:


    //设置为守护线程
    thread.setDaemon(true);
    //启动子线
    thread.start();

実行結果は次のようになります:

上記のように、開始する前にスレッドをデーモン スレッドとして設定します。 ps -eaf |grep java を実行すると、JVM プロセスが終了し、JVM プロセスが表示されないことがわかります。この例では、メイン関数は唯一のユーザー スレッドであり、スレッド スレッドはデーモン スレッドです。メイン スレッドの実行が終了すると、JVM はユーザー スレッドがなくなったことを検出し、JVM プロセスを終了します。

Java では、メイン スレッドが終了した後、JVM は DestroyJavaVM というスレッドを自動的に開始します。このスレッドは、すべてのユーザー スレッドが JVM プロセスを終了するまで待機します。以下は、この結論を証明する簡単な JVM コードです。 JVM コードは最終的に JavaMain c 関数を呼び出します

int JNICALL
JavaMain(void * _args)
{  
  ...
  //执行Java中的main函数 
  (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
  
  //main函数返回值
  ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
  
  //等待所有非守护线程结束,然后销毁JVM进程
  LEAVE();
}

LEAVE は C 言語のマクロ定義です。定義は次のとおりです。

#define LEAVE() \
  do { \
    if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
      JLI_ReportErrorMessage(JVM_ERROR2); \
      ret = 1; \
    } \
    if (JNI_TRUE) { \
      (*vm)->DestroyJavaVM(vm); \
      return ret; \
    } \
  } while (JNI_FALSE)

上記のマクロの機能は実際には、 DestroyJavaVM という名前のスレッド。すべてのユーザー スレッドが終了するまで待ちます。

概要: メインスレッドの終了後すぐに JVM プロセスを終了したい場合は、スレッドの作成時にスレッドをデーモンスレッドとして設定できます。それ以外の場合、メインスレッドの終了後も子スレッドが動作し続けるようにするには、次のようにします。子スレッドが終了するのを待ち、プロセスが終了したら子スレッドをユーザースレッドとして設定します。オープンソースフレームワークTomcatはデーモンスレッドとユーザースレッドを併用して実行します。詳細は公開を楽しみにしてください。 Java 並行プログラミングの基礎に関する並行パッケージ ソース コード分析の書籍。

以上がJava のデーモン スレッドとユーザー スレッドの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。