スレッドスタート:
1。start()とrun()の違いの説明
start():その関数は新しいスレッドを起動することであり、新しいスレッドは対応するrun()メソッドを実行します。 start()を繰り返し呼ぶことはできません。
run():run()は、通常のメンバーメソッドと同じように繰り返し呼ぶことができます。 run()を個別に呼び出すと、run()が現在のスレッドで実行され、新しいスレッドは開始されません!
以下は説明するコードです。
class mythread extends thread {public void run(){...}}; mythread mythread = new mythread(); mythread.start()は新しいスレッドを起動し、新しいスレッドでrun()メソッドを実行します。
mythread.run()は、現在のスレッドでrun()メソッドを直接実行し、run()に新しいスレッドを起動しません。
2。start()とrun()の違いの例
以下では、簡単な例でそれらの違いを示します。ソースコードは次のとおりです。
// demo.javaのソースコードクラスmythread extends thread {public mythread(string name){super(name); } public void run(){system.out.println(thread.currentthread()。getname()+"is running"); }}; public class demo {public static void main(string [] args){thread mythread = new mythread( "mythread"); system.out.println(thread.currentthread()。getname()+"call mythread.run()"); mythread.run(); system.out.println(thread.currentthread()。getname()+"call mythread.start()"); mythread.start(); }}実行結果:
メインコールmythread.run()mainはrunningmain call mythread.start()mythreadが実行されています
結果説明:
(1)thread.currentThread()。getName()は、「現在のスレッド」の名前を取得するために使用されます。現在のスレッドは、CPUで実行されるようにスケジュールされるスレッドを指します。
(2)mythread.run()は「メインスレッドメイン」で呼び出され、run()メソッドは「メインスレッドメイン」で直接実行されます。
(3)mythread.start()は「thread mythread」を開始します。 「Thread MythRead」が開始された後、run()メソッドが呼び出されます。この時点で、run()メソッドは「thread mythread」で実行されます。
スレッド割り込みと終端
1。スレッド割り込み:割り込み()
割り込み()の関数は、スレッドを中断することです。
このスレッドはそれ自体を中断することができます。他のスレッドがこのスレッドの割り込み()メソッドを呼び出すと、許可はCheckAccess()を介してチェックされます。これにより、SecurityExceptionの例外がスローされる場合があります。
スレッドがブロッキング状態にある場合:wait()、wait(long)or wait(long、int)の呼び出しは、待機状態になります(ブロッキング)状態になります。スレッドがブロックしているときに割り込み()メソッドを呼び出すと、その「割り込み状態」がクリアされ、中断されたエクセプトが受信されます。たとえば、スレッドはwait()を介してブロッキング状態に入り、スレッドは割り込み()によって中断されます。 Calling incurte()はすぐにスレッドの割り込みフラグを「true」に設定しますが、スレッドはブロッキング状態にあるため、「割り込みフラグ」はすぐに「false」にクリアされ、割り込みExceptionが生成されます。
スレッドがセレクターセレクターでブロックされている場合、arturts()によって中断される場合。スレッドの割り込みフラグはtrueに設定されており、選択操作からすぐに返されます。
上記の状況に属していない場合、スレッドが割り込み()を介して中断されると、割り込みフラグが「真」に設定されます。
「終了スレッド」を中断しても、操作は発生しません。
2。スレッド終了
スレッド内のstop()およびsuspend()メソッドは、固有の不安のために使用しないことをお勧めします!
次に、まず「ブロッキング状態」と「ランニングステート」でスレッドの終了方法について説明し、次に一般的な方法を要約します。
1。「ブロッキング状態」のスレッドを終了します
通常、「中断」することにより、「ブロッキング状態」のスレッドを終了します。
スレッドがsleep()と呼ばれるためにブロック状態に入ると、wait()、join()、およびその他の方法。この時点でスレッドの割り込み()が呼び出された場合、スレッドの割り込みマークがtrueに設定されます。ブロッキング状態にあるため、割り込みフラグがクリアされ、割り込みExceptionの例外が生成されます。適切になるまで中断exceptionを置くと、次のように形式でスレッドを終了できます。
@OverridePublic void run(){try {while(true){//タスクを実行します...}} catch(arternedexception ie){//中断の例外のため、while(true)ループを終了し、スレッドが終了します! }}注:タスクが継続的に実行されている場合(true)、スレッドがブロッキング状態にあるとき、スレッドの呼び出し()はターゲットexception割り込みを生成します。中断されたキャプチャは外側(真)であるため、while(true)ループを終了します!
注:中断拡張のキャプチャは通常、while(true)ループ本体の外側に配置されるため、while(true)ループは例外が生成されると終了します。それ以外の場合、中断exceptionがwhile(true)ループ本体内にある場合、追加の追加と出口処理が必要です。フォームは次のとおりです。
@overridepublic void run(){while(true){try {// execute task ...} catch(arturnedexception ie){//邪魔されないexceptionはwhile(true)loop bodyです。 //スレッドが中断されたExceptionの例外を生成するとき、(True)は実行され続けることができます!手動で休憩を終了する必要があります。 }}}注:上記の中断exceptionの例外は、whle(true)内で捉えられます。中断exceptionの例外が生成されると、キャッチによって処理されず、まだ(真の)ループ本体です。 while(true)ループ本体を終了するには、while(true)を終了する追加の操作を実行する必要があります。
2。「実行中の状態」でスレッドを終了します
通常、「マーキング」によって「ランニング状態」のスレッドを終了します。その中には、「割り込みフラグ」と「追加フラグの追加」が含まれています。
(1)「割り込みフラグ」を介してスレッドを終了します。
フォームは次のとおりです。
@overridepublic void run(){while(!is intertrupted()){//タスクを実行...}}}説明:is unterrurded()は、スレッドの割り込みフラグが真であるかどうかを決定します。スレッドが実行されている場合、それを終了する必要がある場合。スレッドの割り込み()メソッドを呼び出すことができ、スレッドの割り込みフラグが真でマークされます。つまり、ISERTERRURDED()がtrueを返します。この時点で、whileループは終了します。
注:割り込み()は、「ランニングステート」のスレッドを終了しません!スレッドの割り込みフラグをtrueに設定します。
(2)「追加のマークを追加」に渡します。
フォームは次のとおりです。
private volatile boolean flag = true; protected void stoptask(){flag = false;}@overridepublic void run(){while(flag){//タスクを実行...}}}}説明:スレッドにはフラグタグがあり、そのデフォルト値は真です。また、stoptask()を提供して、フラグタグを設定します。スレッドを終了する必要がある場合、スレッドのstoptask()メソッドを呼び出すと、スレッドがwhileループを終了する可能性があります。
注:フラグは、フラグの可視性を確保するための揮発性タイプとして定義されています。つまり、他のスレッドがstoptask()を介してフラグを変更した後、このスレッドは変更されたフラグ値を見ることができます。
「ブロック状態」および「実行状態」のスレッドの終了方法を包括的に、より一般的な終了スレッドは次のとおりです。
@OverridePublic void run(){try {//1。ISERTENRURDED()は、割り込みが真でマークされている限り、スレッドが終了することを保証します。 whip( }} 3。終端スレッドの例
割り込み()は、多くの場合、「ブロッキング状態」スレッドを終了するために使用されます。次の例を参照してください。
// demo1.javaのソースコードクラスmythread extends thread {public mythread(string name){super(name); } @Override public void run(){try {int i = 0; while(!is intertrupted()){swrep.sleep(100); // 100ms I ++スリープ; system.out.println(thread.currentthread()。getName()+"("+this.getState()+")loop"+i); }} catch(arturnedexception e){system.out.println(thread.currentthread()。getname()+"("+this.getState()+")catch interruptedException。"); }}} public class demo1 {public static void main(string [] args){try {thread t1 = new Mythread( "T1"); //新しい「スレッドT1」System.out.println(t1.getName()+"("+t1.getState()+")を作成します。 t1.start(); //「スレッドt1」System.out.println(t1.getName()+"("+t1.getState()+")が開始されます。"); //メインスレッドは300msで眠り、メインスレッドはT1に「割り込み」命令を送信します。 thread.sleep(300); t1.interrupt(); system.out.println(t1.getname()+"("+t1.getState()+")が中断されます。"); //メインスレッドは300ミリ秒間スリープし、T1のステータスをチェックします。 thread.sleep(300); System.out.println(t1.getName()+"("+t1.getState()+")が中断されました。"); } catch(arturnedexception e){e.printstacktrace(); }}}実行結果:
T1(new)はnew.t1(実行可能)が開始されます。t1(実行可能)ループ1t1(実行可能)ループ2t1(timed_waiting)が中断されます。
結果説明:
(1)メインスレッドメインは、新しいMythRead( "T1")を介してスレッドT1を作成し、T1.start()からスレッドT1を起動します。
(2)T1が開始された後、割り込みフラグは継続的にチェックされます。割り込みフラグが「false」の場合、100ミリ秒間眠ります。
(3)T1睡眠後、メインスレッドメインに切り替えます。メインスレッドが再び実行されると、t1.interprupt()が実行され、スレッドT1が中断されます。 T1が割り込み命令を受け取った後、T1の割り込みフラグが「false」に設定され、中断端切りがスローされます。 T1のrun()メソッドでは、それはループ本体の外側にある例外です。したがって、ループは終了します。
上記の結果をわずかに変更し、whileループボディにrun()メソッドの中断exception例外をキャッチするコードブロックを移動しました。
// demo2.javaのソースコードクラスmythread extends thread {public mythread(string name){super(name); } @Override public void run(){int i = 0; while(!is interpurded()){try {thread.sleep(100); // 100msのスリープ} catch(arternedexception ie){system.out.println(thread.currentthread()。getname()+"("+this.getState()+")catch arterntedexception。"); } i ++; system.out.println(thread.currentthread()。getName()+"("+this.getState()+")loop"+i); }}} public class demo2 {public static void main(string [] args){try {thread t1 = new Mythread( "T1"); //新しい「スレッドT1」System.out.println(t1.getName()+"("+t1.getState()+")を作成します。 t1.start(); //「スレッドt1」System.out.println(t1.getName()+"("+t1.getState()+")が開始されます。"); //メインスレッドは300msで眠り、メインスレッドはT1に「割り込み」命令を送信します。 thread.sleep(300); t1.interrupt(); system.out.println(t1.getname()+"("+t1.getState()+")が中断されます。"); //メインスレッドは300ミリ秒間スリープし、T1のステータスをチェックします。 thread.sleep(300); System.out.println(t1.getName()+"("+t1.getState()+")が中断されました。"); } catch(arturnedexception e){e.printstacktrace(); }}}実行結果:
T1(new)is new.t1(実行可能)が開始されます。t1(実行可能)ループ1t1(実行可能)ループ2t1(timed_waiting)が中断されます。ループ6T1(実行可能)ループ7T1(実行可能)ループ8T1(実行可能)ループ9 ...
結果説明:
プログラムはデッドループを入力しました!
なぜこれが起こっているのですか?これは、T1が「状態を待っている」(ブロッキング)しているときに、T1が割り込み()によって中断されるためです。この時点で、割り込みフラグがクリアされます[中断されます()falseが返されます)、および中断されたExceptionの例外がスローされます[この例外はWhile Loop Bodyでキャッチされます]。したがって、T1は自然に悪循環に入ります。
この問題を解決するには、例外をキャッチするときにwhileループを終了するために追加の処理が必要です。たとえば、BreakまたはMythread Catchに戻る(中断のあるException)を追加すると、問題が解決できます。
「追加のタグを追加」して「ステータス状態」を終了するスレッドの例は次のとおりです。
// demo3.javaのソースコードクラスmythread extends thread {private volatile boolean flag = true; public void stoptask(){flag = false; } public mythread(string name){super(name); } @Override public void run(){synchronized(this){try {int i = 0; while(flag){thread.sleep(100); // 100ms I ++スリープ; system.out.println(thread.currentthread()。getName()+"("+this.getState()+")loop"+i); }} catch(arturnedexception ie){system.out.println(thread.currentthread()。getname()+"("+this.getState()+")catch interruptedException。"); }}}} public class demo3 {public static void main(string [] args){try {mythread t1 = new mythread( "t1"); //新しい「スレッドT1」System.out.println(t1.getName())+"("+t1.getState()+")を作成します。 t1.start(); //「スレッドt1」System.out.println(t1.getName()+"("+t1.getState()+")が開始されます。"); //メインスレッドは300msで眠り、メインスレッドはT1に「割り込み」命令を送信します。 thread.sleep(300); t1.stoptask(); system.out.println(t1.getname()+"("+t1.getState()+")が中断されます。"); //メインスレッドは300ミリ秒間スリープし、T1のステータスをチェックします。 thread.sleep(300); System.out.println(t1.getName()+"("+t1.getState()+")が中断されました。"); } catch(arturnedexception e){e.printstacktrace(); }}}実行結果:
T1(new)はnew.t1(実行可能)が開始されます。t1(実行可能)ループ1t1(実行可能)ループ2t1(timed_waiting)が中断されます。t1(実行可能)ループ3t1(終端)が中断されました。