マルチスレッドは、Javaの非常に重要な知識ポイントです。ここでは、編集者がJavaスレッドマルチスレッドを要約しています。これは非常に便利です。私はあなたがそれをマスターすることができることを願っています。
1。スレッドと5つの基本的な状態のライフサイクル
Javaのスレッドのライフサイクルについては、まず次の古典的な写真を見てみましょう。
上記の図は、基本的に、Javaのマルチスレッドの重要な知識ポイントをカバーしています。上記の図の知識ポイントをマスターすると、基本的にJavaでマルチスレッドをマスターします。主に:
Javaスレッドには5つの基本状態があります
新しい状態(新しい):スレッドオブジェクトペアが作成されると、次のような新しい状態に入ります。
Ready State(実行可能):スレッドオブジェクトのstart()メソッド(t.start();)の場合、スレッドは準備ができた状態に入ります。準備が整った状態のスレッドは、スレッドの準備ができており、CPUがいつでも実行をスケジュールするのを待っていることを意味します。T.Start()が実行された直後にスレッドが実行されることではありません。
ランニング状態:CPUが準備ができた状態でスレッドのスケジュールを開始すると、スレッドを本当に実行できます。つまり、実行中の状態に入ります。注:Ready Stateは、実行状態への唯一のエントリです。つまり、スレッドが実行されて実行された状態に入りたい場合、最初に準備ができている必要があります。
ブロック状態:何らかの理由で、実行状態のスレッドがCPUの使用を一時的に放棄し、実行を停止します。この時点で、ブロッキング状態に入ります。実行中の状態に入るために、CPUから再び呼び出される機会はありません。
ブロッキングの理由によると、ブロッキング状態は3つのタイプに分けることができます。
1。ブロッキングを待つ:実行中の状態のスレッドは、wait()メソッドを実行して、スレッドがブロッキング状態を待機することを入力します。
2。同期ブロッキング - スレッドは、同期化された同期ロックを取得できません(ロックは他のスレッドで占有されているため)、同期されたブロッキング状態に入ります。
3。その他のブロッキング - スレッドは、スレッドのSleep()またはJoin()を呼び出すか、I/O要求を発行することにより、ブロッキング状態を入力します。 Sleep()状態がタイムアウトしたとき、Join()がスレッドが終了またはタイミングアウトするのを待っているか、I/O処理が完了した場合、スレッドは準備ができた状態に再入力されました。
DEAD:スレッドは、例外のために実行されるか、run()メソッドを終了するか、スレッドがライフサイクルを終了しました。
2。Java Multithreadsの作成とスタートアップ
Javaにはスレッド作成には3つの基本的な形式があります
1.スレッドクラスを継承し、クラスのrun()メソッドをオーバーライドします。
class mythread extends thread {private int i =; @overridepublic void run(){for(i =; i <; i ++){system.out.println(thread.currentthread()。 {system.out.println(thread.currentthread()。getName() + "" + i); if(i ==){thread mythread = new mythread(); //新しいスレッドMythReadを作成するこのスレッドは、新しい状態スレッドmythread = new MythRead()に入ります。 //新しいスレッドを作成するmythreadこのスレッドは、新しい状態mythread.start()に入ります。 // start()メソッドを呼び出して、スレッドにReady State mythread.start()を入力させる; // start()メソッドを呼び出して、スレッドに対応状態を入力する}}}}上に示すように、スレッドクラスを継承し、run()メソッドをオーバーライドします。新しいスレッドクラスのmythReadが定義されます。ここでは、run()メソッドのメソッドボディは、スレッドが完了する必要があるタスクを表し、スレッド実行ボディと呼ばれます。このスレッドクラスオブジェクトを作成すると、新しいスレッドが作成され、新しいスレッド状態に入ります。スレッドオブジェクトによって参照されるstart()メソッドを呼び出すことにより、スレッドは準備ができた状態に入ります。現時点では、CPUスケジューリングのタイミングに応じて、スレッドをすぐに実行できない場合があります。
2。実行可能なインターフェイスを実装し、インターフェイスのrun()メソッドをオーバーライドします。 run()メソッドは、スレッド実行本体でもあり、実行可能な実装クラスのインスタンスを作成し、このインスタンスをスレッドクラスのターゲットとして使用してスレッドオブジェクトを作成します。スレッドオブジェクトは実際のスレッドオブジェクトです。
class myRunnable runnable {private int i =; @overridepublic void run(){for(i =; i <; i ++){shured.currentthread()。 {system.out.println(thread.currentthread()。getname() + "" + i); if(i ==){runnable myRunnable = new myRunnable(); //実行可能な実装クラススレッドのオブジェクトを作成するスレッド= newスレッド(myrunnable); // myrunnableをスレッドターゲットとして使用して、新しいスレッドスレッドを作成する= newスレッド(myrunnable); thread.start(); // start()メソッドを呼び出して、スレッドにready state swrep.start();}}}}}を入力するようにします誰もが新しいスレッドを作成する上記の2つの方法に精通していると思います。では、スレッドと実行可能な関係は何ですか?まず次の例を見てみましょう。
public class Sthreadtest {public static void main(string [] args){for(int i =; i <; i ++){system.out.println(shood.currentthread()。getName() + "" + i); if(i ==){runnable myrunnable = new myrunnable( mythread(myrunnable); shood.start();}}}} class myrunnable runnable {private int i =; @overridepublic void run(){system.out.println( "in myrunnable run"); "+i);}}} class mythread extends thread {private int i =; public mythread(runnable runnable){super(runnable);}@overridepublic void run(){system.out.println(" in mythread run "); + "" + i);}}}同様に、実行可能なインターフェイスを実装するスレッドの作成にも同じことが言えます。違いは、
スレッドスレッド= new mythread(myrunnable);
では、この方法は新しいスレッドを正常に作成できますか?答えはイエスです。この時点でのスレッド実行本体に関しては、myrunnableインターフェイスのrun()メソッドまたはmythreadクラスのrun()メソッドですか?出力を通じて、スレッド実行本体がMythReadクラスのrun()メソッドであることがわかります。実際、スレッドクラス自体が実行可能なインターフェイスを実装し、run()メソッドが実行可能なインターフェイスで最初に定義されるため、理由は非常に単純です。
public interface runnable {public abstract void run();}スレッドクラスの実行可能なインターフェイスでのrun()メソッドの実装を見てみましょう。
@overridepublic void run(){if(target!= null){target.run();}}}つまり、スレッドクラスでrun()メソッドを実行すると、ターゲットのrun()メソッドが最初に決定されます。それが存在する場合、ターゲットのrun()メソッドが実行されます。つまり、実行可能なインターフェイスを実装し、run()メソッドを上書きするクラスのrun()メソッドです。ただし、上記の列では、多型が存在するため、スレッドクラスのrun()メソッドはまったく実行されませんが、ランタイムタイプ、つまりMythreadクラスのrun()メソッドは直接実行されます。
3.呼び出し可能なインターフェイスを使用してスレッドを作成します。具体的には、呼び出し可能なインターフェイスの実装クラスを作成し、Clall()メソッドを実装します。 FutureTaskクラスを使用して、呼び出し可能な実装クラスオブジェクトをラップし、このFutureTaskオブジェクトをスレッドオブジェクトのターゲットとして使用してスレッドを作成します。
少し複雑に思えますが、例を直接見るかどうかは明らかです。
public class threadtest {public static void main(string [] args){callable <integer> mycallable = new mycallable(); // myCallableオブジェクトFutureTask <Integer> ft = new FutureTask <Integer>(myCallable); // futureTaskを使用して、(int i =; i <; i ++){system.out.println(thread.currentthread()。getName() + "" + i); if(i ==){thread thread = newスレッド(ft); // futureTaskオブジェクトスレッドオブジェクトスレッドのターゲットとして新しいスレッドを作成します。Start(); //スレッドは準備ができた状態に入ります}} system.out.println( "ループ実行のメインスレッドが完了..."); try {int sum = ft.get(); //新しく作成された新しいスレッドSystem.out.println( "sum =" + sum);} catch(arturnedStackTrace e){e.printStackTrace();} catch(executionException e){e.printstacktrace();}}}} caste(executionextrace();} catch(interrupedextrace e);} catch(sum = " + sum); call()メソッドには、return値@overridepublic integer call(){int sum =; for(; i <; i ++){system.out.println(thread.currentthread()。getname() +"" +i); sum += i;} return sum;}}}まず、呼び出し可能なインターフェイスを実装する際に、run()メソッドはrun()メソッドではなく、call()メソッドであることがわかりました。この呼び出し()メソッドはスレッド実行本体であり、返品値もあります!新しいスレッドを作成するとき、MyCallableオブジェクトはFutureTaskにラップされ、スレッドオブジェクトのターゲットとしても使用されます。次に、FutureTaskクラスの定義を見てください。
Public Class FutureTask <V>実装runnableFuture <v> {// ....} public interface runnableFuture <v>拡張runnable、future <v> {void run();}したがって、FutureTaskクラスは実際に実行可能なインターフェースと将来の両方のインターフェイスを実装しているため、将来と実行可能な二重特性を備えていることがわかりました。実行可能な機能を介して、スレッドオブジェクトのターゲットとして使用でき、将来の機能により、新しく作成されたスレッドでcall()メソッドの返信値を取得できます。
このプログラムを実行した後、Sum = 4950が常に最後の出力であることがわかります。 「ループのメインスレッドが実行されました...」は、子スレッドループの中央で出力される可能性があります。 CPUのスレッドスケジューリングメカニズムから、「ループのメインスレッドが実行された...」の出力タイミングに問題がないことを知っています。
その理由は、子スレッドのcall()メソッドがft.get()メソッドを介して取得されると、子スレッドのメソッドがまだ実行されていない場合、ft.get()メソッドは、返品値が取得される前にcall()メソッドが実行されるまでブロックされるためです。
上記は、主に3つの一般的なスレッド作成方法を説明しています。スレッドの起動については、それらはすべてスレッドオブジェクトのstart()メソッドと呼ばれます。 Start()メソッドを同じスレッドオブジェクトで2回呼び出すことはできないことに注意することが重要です。
iii。 Java Multithreadingの準備、実行、および死亡のステータス
準備ができた状態は実行状態に変換されます。このスレッドがプロセッサリソースを取得するとき。
実行状態は準備が整った状態に変換されます。このスレッドが積極的にevel()メソッドを呼び出すとき、または実行中にプロセッサリソースを失います。
実行状態は死んだ状態に変換されます:スレッド実行本体が完了するか、例外が発生したとき。
ここでは、スレッドのevel()メソッドが呼び出されると、スレッドが実行状態から対応状態への遷移がありますが、CPUの既製状態のスレッドには特定のランダム性があることに注意してください。したがって、aスレッドがhired()メソッドを呼び出した後、CPUはまだAスレッドをスケジュールしていることがあります。
実際のビジネスニーズにより、スレッドを特定の機会に終了する必要があることがよくあります。現在最も一般的な方法は、ブール変数を設定することであり、条件が満たされると、スレッド実行本体が迅速に実行されます。のように:
public class threadtest {public static void main(string [] args){myrunnable myrunnable = new myrunnable(); swreet = newスレッド(myRunnable); {thread.start();} if(i ==){myrunnable.stopthread();}}}}} myRunnable runnable {private boolean stop; @overridepublic void run(){for(int i =; i <&&! " + i);}} public void stopthread(){this.stop = true;}}}上記は、編集者が紹介したJavaスレッドマルチスレッドの包括的な分析です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!