この記事は、主にJavaの背景スレッドの関連する問題を次のように研究しています。
Javaには背景スレッドがあることを聞いたことがありません。一般的に、JVM(Java Virtual Machine)には、一般に、ユーザースレッドとバックグラウンドスレッドの2種類のスレッドが含まれています。いわゆるデーモンスレッドは、プログラムが実行されているときにバックグラウンドで共通のサービスを提供するスレッドを指します。このスレッドはプログラムの不可欠な部分ではありません。したがって、すべての非バックグラウンドスレッドが終了すると、つまりユーザースレッドが終了すると、プログラムが終了します。同時に、プロセス内のすべての背景スレッドを殺します。逆に、バックグラウンド以外のスレッドがまだ実行されている限り、プログラムは終了しません。非梱包スレッドよりもmain()を実行する方が良いです。
この機能に基づいて、仮想マシンのすべてのユーザースレッドが実行されてから終了すると、デーモンスレッドにはサービスオブジェクトがなく、JVMが終了します。
これは、JDKソースコードで説明されています。
*このスレッドを{@linkplain #isdaemon daemon}スレッドのいずれかとしてマークします
*またはユーザースレッド。 Java仮想マシンは、唯一の場合に終了します
*スレッドの実行はすべてデーモンスレッドです。
1。バックグラウンドスレッドを開始するための条件:
/*このスレッドを背景スレッドとして設定するためにスレッドを起動する前に、setDaemon()メソッドを呼び出す必要があります。 *このプログラムでは、文字列を入力した後、メインスレッドは実行を停止します*その後、プログラムで実行できるユーザーのスレッドはありません。したがって、バックグラウンドスレッドが停止します * JVMは停止し、興味のある読者は自分で試してみることができます */パブリッククラスのDaemonrunnerはrunnable {@override public void run(){while){for(int i = 0; i <3; i ++){system.out.out.println( "daemon thread"+i); "+i) daemon = newスレッド(new daemonrunner()); daemon.setdaemon(true); daemon.start(); scanner s = new scanner(system.in); string string = s.nextline(); runtime.getruntime()。 exit "); try {timeunit.milliseconds.sleep(50);} catch(arturnedexception e){e.printstacktrace();}}});}}}}2.バックグラウンドスレッドで開始されたすべてのスレッドは、バックグラウンドスレッドに属します。それらがバックグラウンドスレッドであることを明示的に指定することはありませんが、実際にはバックグラウンドスレッドです。
/* isDaemon()メソッドを呼び出すことにより、スレッドが背景スレッドであるかどうかを判断できます。それが背景スレッドの場合 *で作成されるスレッドは、この例では、バックグラウンドスレッド *に自動的に設定されます。デーモンスレッドはバックグラウンドモードに設定され、多くの子スレッドを導き出します。これらのスレッドは *バックグラウンドモードに設定されていませんが、実際にはバックグラウンドスレッドです。次に、デーモンスレッドは無限ループに入り、ループ*の収量メソッドを呼び出してコントロールを他のスレッドまたはプロセスに引き渡す*/classデーモンを実装します{] runnable {t = newスレッド[10];@オーバーライドpublic void run(){for(int i = 0; i <t.length; i ++){t [i] =ニュースレッド(ニュースレッド(ニュースレッド(ニュースレッド(ニュースレッド) daemonspawn()); t [i] .start(); system.out.println( "daemonspawn" + i + "Started");} for {thread.yield();}}} class daemonspawnはrunnable {@override public void run(){while(true){thread.yield();}}} public class daemons {public static void main(string [] args){thread d = new swery(new swreat(new daemon()); d.setdaemon(true); d.start(); system.out.println( "d.isdaemon()=" + d.isdaemon()); try {timeunit.seconds.sleep(1); //起動背景のスレッドを特定の実行時間を取得します。 } catch(arternedexception e){e.printstacktrace();}}}最終的な実行結果は次のとおりです。
d.isdaemon()= true
daemonspawn 0STARTED
DaeMonspawn 1STARTED
DaeMonspawn 2STARTED
DaeMonspawn 3Started
DaeMonspawn 4Started
Daemonspawn 5Started
DaeMonspawn 6STARTED
Daemonspawn 7Started
DaeMonspawn 8STARTED
DaeMonspawn 9Started
t [0] .isdaemontrue
t [1] .isdaemontrue
t [2] .isdaemontrue
t [3] .isdaemontrue
t [4] .isdaemontrue
t [5] .isdaemontrue
t [6] .isdaemontrue
t [7] .isdaemontrue
t [8] .isdaemontrue
t [9] .isdaemontrue
3. Executors.newCachedThreadPool()メソッドを指定して、ThreadFactoryオブジェクトを指定します。このようにして、背景スレッドとして開始するスレッドを設定することもできます。
/*この例では、この静的コンストラクター:executors.newcachedthreadpool(new daemonthreadfactory()*スレッドファクトリーオブジェクトを渡すことができます。したがって、この方法を介して背景スレッドとして開始するスレッドを設定できます*これは注意してください。 Thread(r); setdaemon(true); return t;}/*メイン方法では、主な方法で「System.out.println」(「すべてのDameonsが開始されました」)。メインラインは実行されます *すべてのバックグラウンドスレッドは実行されます。 e){system.out.println( "中断");}} public static void main(string [] args){executorservice execors.newcachedthreadpool(new daemonthreadfactory()) start "); try {timeunit.milliseconds.sleep(500);} catch(arturnedexception e){e.printstacktrace();}}}}最終的な出力結果は次のとおりです。
すべてのダメオンが始まりました
スレッド[スレッド3,5、メイン] scurrency.daemonfromfactory@56214c1
スレッド[スレッド2,5、メイン] scurrency.daemonfromfactory@5724147d
スレッド[スレッド-0,5、メイン] scurrency.daemonfromfactory@144fe080
スレッド[スレッド1,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@104FA29E
スレッド[スレッド8,5、メイン] scurrency.daemonfromfactory@5b069a7f
スレッド[スレッド9,5、メイン] scurrency.daemonfromfactory@1a7288d1
スレッド[スレッド-7,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@25144C3E
スレッド[スレッド4,5、メイン] scurrency.daemonfromfactory@288523d
スレッド[スレッド6,5、メイン] scurrency.daemonfromfactory@1edae2a8
スレッド[スレッド5,5、メイン] scurrency.daemonfromfactory@626007aa
スレッド[スレッド3,5、メイン] scurrency.daemonfromfactory@56214c1
スレッド[スレッド2,5、メイン] scurrency.daemonfromfactory@5724147d
スレッド[スレッド6,5、メイン] scurrency.daemonfromfactory@1edae2a8
スレッド[スレッド5,5、メイン] scurrency.daemonfromfactory@626007aa
スレッド[スレッド4,5、メイン] scurrency.daemonfromfactory@288523d
スレッド[スレッド9,5、メイン] scurrency.daemonfromfactory@1a7288d1
スレッド[スレッド-7,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@25144C3E
スレッド[スレッド8,5、メイン] scurrency.daemonfromfactory@5b069a7f
スレッド[スレッド1,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@104FA29E
スレッド[スレッド-0,5、メイン] scurrency.daemonfromfactory@144fe080
スレッド[スレッド2,5、メイン] scurrency.daemonfromfactory@5724147d
スレッド[スレッド3,5、メイン] scurrency.daemonfromfactory@56214c1
スレッド[スレッド6,5、メイン] scurrency.daemonfromfactory@1edae2a8
スレッド[スレッド1,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@104FA29E
スレッド[スレッド-0,5、メイン] scurrency.daemonfromfactory@144fe080
スレッド[スレッド-7,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@25144C3E
スレッド[スレッド8,5、メイン] scurrency.daemonfromfactory@5b069a7f
スレッド[スレッド5,5、メイン] scurrency.daemonfromfactory@626007aa
スレッド[スレッド9,5、メイン] scurrency.daemonfromfactory@1a7288d1
スレッド[スレッド4,5、メイン] scurrency.daemonfromfactory@288523d
スレッド[スレッド2,5、メイン] scurrency.daemonfromfactory@5724147d
スレッド[スレッド3,5、メイン] scurrency.daemonfromfactory@56214c1
スレッド[スレッド8,5、メイン] scurrency.daemonfromfactory@5b069a7f
スレッド[スレッド-7,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@25144C3E
スレッド[スレッド4,5、メイン] scurrency.daemonfromfactory@288523d
スレッド[スレッド6,5、メイン] scurrency.daemonfromfactory@1edae2a8
スレッド[スレッド1,5、メイン] CONCURRENCY.DAEMONFROMFACTORY@104FA29E
スレッド[スレッド-0,5、メイン] scurrency.daemonfromfactory@144fe080
スレッド[スレッド9,5、メイン] scurrency.daemonfromfactory@1a7288d1
スレッド[スレッド5,5、メイン] scurrency.daemonfromfactory@626007aa
スレッド[スレッド3,5、メイン] scurrency.daemonfromfactory@56214c1
スレッド[スレッド2,5、メイン] scurrency.daemonfromfactory@5724147d
スレッド[スレッド8,5、メイン] scurrency.daemonfromfactory@5b069a7f
4.まず、ユーザースレッドが突然終了すると、バックグラウンドスレッドが最終句を実行せずに実行方法を終了することを認識する必要があります。
/*このプログラムを呼び出すと、最終的な句が実行されないことがわかりますが、SetDaemon()への呼び出しをコメントすると、*最終的な句が実行されることがわかります。*この動作は正しいです。あなたが最終的にあなたの前で与えた約束に基づいてこの行動を望まないとしても。しかし、これは事実です。最後の非バックグラウンドスレッドが終了すると、背景スレッドが突然停止します。 Main()が終了すると、JVMはすぐにすべての *スレッドをバックグラウンドで閉じます。エレガントな方法で背景スレッドを閉じることができないので、それらはほとんど良い考えではありません。執行者によって制御されるすべてのタスクを同時に閉じることができるため、非収容執行者は通常 *より良い方法です。 */class adaemonはrunnable {@override public void run(){system.out.println( "adaemon"); {timeunit.seconds.sleep(1)を試してください。 } catch(arturnedexception e){system.out.println( "arturtededexception"を介して終了 "); }最後に{system.out.println( "これは常に実行する必要がありますか?"); }}} public class daemonsdontrunfinally {public static void main(string [] args){thread t = newスレッド(new adaemon()); T.SetDaemon(True); t.start(); }}最終出力の結果は次のとおりです。
Adaemonを開始します
ただし、状況が次の状況になった場合、出力の結果は再び異なります。
クラスAdaemonはrunnable {@override public void run(){system.out.println( "adaemon"); {timeunit.seconds.sleep(1)を試してください。 } catch(arturnedexception e){system.out.println( "arturtededexception"を介して終了 "); }最後に{system.out.println( "これは常に実行する必要がありますか?"); }}} public class daemonsdontrunfinally {public static void main(string [] args){thread t = newスレッド(new adaemon()); T.SetDaemon(True); t.start(); {timeunit.seconds.sleep(1)を試してください。 } catch(arturnedexception e){e.printstacktrace(); }}}メインスレッドが突然終了しないため、バックグラウンドスレッドはメインスレッド中に実行時間を取得するため、最終的な印刷結果は次のとおりです。
Adaemonを開始します
これは常に実行する必要がありますか?
上記は、Javaのバックグラウンドスレッドインスタンスの分析に関するこの記事のすべての内容であり、すべての人に役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!