1。スレッドとプロセス
1。スレッドとプロセスの違いは何ですか:
スレッドとは、実行中にプログラムコードを実行できる実行ユニットを指します。 Java言語では、スレッドには4つの状態があります:実行、準備、中断、終了。
プロセスとは、実行されているプログラムを指します。スレッドは、何かすることがあるときに軽量プロセスになります。プログラム実行の最小単位を持っています。プロセスには複数のスレッドがあります。各スレッドは、プログラムの内部パワースペース(コードセグメント、データセグメント、ヒープスペース)とプロセスレベルのリソース(オープンファイルなど)を共有していますが、各スレッドには独自のスペースがあります。
2.なぜマルチプロセスを使用するのですか?<br />主にオペレーティングシステムレベルに次の側面があります。
- マルチスレッドを使用すると、プログラムの応答時間を短縮できます。操作が時間がかかる場合、または長い待ち時間で立ち往生している場合、プログラムはマウスやキーボードなどの操作に応答しません。マルチスレッドを使用した後、この時間のかかるスレッドは、実行のために別のスレッドに割り当てることができ、プログラムのより良いインタラクティブ性になります。
- スレッドの作成とオーバーヘッドの切り替えはプロセスに比べて安価ですが、マルチスレッドはデータ共有において非常に効率的です。
-Multi-CPUまたはマルチコアコンピューターには、マルチスレッドを実行する機能があります。単一のプロセスを使用すると、コンピューターリソースが再利用されないため、リソースの膨大な無駄になります。マルチCPUコンピューターでマルチスレッドを使用すると、CPUの使用率が向上します。
- マルチスレッドを使用すると、プログラムの構造を簡素化し、理解して維持できるようになります。
2。スレッドの作成<br />通常、マルチスレッドの実装には3つの方法があり、最初の2つは最も一般的に使用される方法です。
1。スレッドクラスを継承し、run()メソッドをオーバーライドします
スレッドは、基本的に実行可能なインターフェイスを実装するインスタンスです。 start()メソッドを呼び出した後、マルチスレッドコードをすぐに実行するのではなく、代わりにスレッドを実行することに注意する必要があります。いつマルチスレッドコードを実行するかは、オペレーティングシステムによって決定されます。
主な手順は次のとおりです。
(1)スレッドクラスのサブクラスを定義し、クラスの実行方法をオーバーライドします。ランメソッドのメソッド本体は、スレッドが完了したいタスクを表します。したがって、run()メソッドは実行本体と呼ばれます。
(2)スレッドサブクラスのインスタンスを作成します。つまり、スレッドオブジェクトを作成します。
(3)スレッドオブジェクトのstart()メソッドを呼び出して、スレッドを開始します。
public class testthread extends thread {public void run(){system.out.println( "hello world"); } public static void main(string [] args){thread mthread = new testThread(); mthread.start(); }} 2。実行可能なインターフェイスを実装し、インターフェイスのrun()メソッドを実装します
主な手順は次のとおりです。
(1)クラスをカスタマイズし、実行可能なインターフェイスを実装し、run()メソッドを実装します。
(2)スレッドサブクラスのインスタンスを作成し、パラメーターとして実行可能なインターフェイスを実装するオブジェクトでスレッドオブジェクトをインスタンス化します。
(3)スレッドの開始方法を呼び出してスレッドを開始します。
public class testrunnable runnable {public void run(){system.out.println( "hello world"); }} public class testrunnable {public static void main(string [] args){testrunnable mtestrunnable = new testrunnable();スレッドmthread = newスレッド(mtestrunnable); mthread.start(); }} 3。呼び出し可能なインターフェイスを実装し、call()メソッドをオーバーライドします
呼び出し可能なインターフェイスは、実際にはエグゼキューターフレームワークの機能的なクラスです。呼び出し可能なインターフェイスは実行可能なインターフェイスに似ていますが、runnableよりも強力な関数を提供します。これは、主に次の3つのポイントに現れます。
(1)callableは、タスクが受け入れられた後、返品値を提供でき、実行可能な機能はこの関数を提供できません。
(2)callableのcall()メソッドは例外をスローできますが、実行可能なrun()メソッドは例外をスローすることはできません。
(3)Callableを実行すると、将来のオブジェクトを取得できます。将来のオブジェクトは、イブラヒモビッチの計算の結果を表し、計算が完了したかどうかを確認する方法を提供します。スレッドは非同期計算モデルに属しているため、他のスレッドから関数の戻り値を取得することは不可能です。この場合、ターゲットスレッドがcall()メソッドを呼び出すときに、将来を使用してcall()メソッドを監視できます。ただし、結果を取得するためにFuture get()メソッドが呼び出されると、現在のスレッドはcall()メソッドの返された結果をブロックし、把握します。
public class testcallable {//スレッドクラスの作成public static class mytestcallable Callable {public string call()throws Exception {retun "Hello World"; }} public static void main(string [] args){myTestCallable mmyTestCallable = new MyTestCallable(); executorservice mexecutorservice = executors.newsinglethreadpool();将来のmfuture = mexecutorservice.submit(mmytestcallable); try {//スレッドが終了して結果system.out.println(mfuture.get())を返すのを待っています。 } catch(Exception e){e.printstacktrace(); }}}上記のプログラムの出力結果は次のとおりです。
これらの3つの方法のうち、実行可能なインターフェイスを実装することを一般的に推奨しています。その理由は、最初に、スレッドクラスは派生クラスで書き換えることができるさまざまな方法を定義しますが、run()メソッドのみを書き直す必要があります。これは、このスレッドの主な機能を実現する必要があります。第二に、クラスを強化または修正する必要がある場合は、クラスを継承する必要があります。したがって、スレッドクラスの他のメソッドをオーバーライドする必要がない場合は、この場合に実行可能なインターフェイスを実装することをお勧めします。
3。割り込みスレッド<br />スレッドのrun()メソッドがメソッド本体の最後のステートメントを実行し、返されたステートメントを実行することにより、またはメソッドに巻き込まれていない例外がキャプチャされない場合に、スレッドが終了します。以前のバージョンのJavaには停止方法がありましたが、他のスレッドはスレッドを終了するために呼び出すことができましたが、この方法は現在廃止されました。
割り込み方式を使用して、スレッドの終了を要求できます。スレッドが割り込みメソッドを呼び出すと、スレッドの割り込み状態が設定されます。これは、スレッドにはないブールフラグです。各スレッドは、このフラグを随時確認して、スレッドが中断されているかどうかを判断する必要があります。
スレッドが設定されているかどうかを確認するには、thread.currentthread()を呼び出すことができます。
while(!thread.currentthread()。is unterrupted()){何かをする}ただし、スレッドがブロックされている場合、割り込み状態を検出できません。これは、中断拡張が生成される場所です。ブロックされたスレッドで割り込みメソッドが呼び出された場合(スリープまたは待機と呼ばれます)。ブロッキングコールは、中断されたエクセプトによって中断されます。
各反復後に睡眠方法(またはその他の中断可能な方法)が呼び出された場合、途切れた検出は不要で役に立たない。割り込み状態が設定されているときに睡眠方法が呼び出された場合、睡眠はしませんが、状態をクリアして中断した例を投げます。したがって、ループでスリープを呼び出す場合は、割り込みステータスを検出しないでください。また、中断されたエクセプトをキャッチしてください。
多くの公開されたコードでは、中断されたエクセプトが非常に低いレベルで抑制されることがわかります。
void mytask(){... try {sleep(50)} catch(arturnedexception e){...}}これをしないでください。キャッチに利点があると思わない場合は、2つの合理的な選択肢があります。
CACTでthread.currentthread()。interrup()を呼び出して、割り込み状態を設定します。発信者はそれを検出できます。より良いオプションは、tryステートメントブロックを使用して完成したブロックをキャプチャすることなく、Throw arturtedexceptionを使用してメソッドをマークすることです。このようにして、発信者はこの例外をキャッチできます。
void mytask()スロー邪魔をしますexception {sleep(50)}4。スレッドの状態
(1)。新しいステータス(新しい):新しいスレッドオブジェクトが作成されます。
(2)。 Ready State(実行可能):スレッドオブジェクトが作成された後、他のスレッドはオブジェクトのstart()メソッドを呼び出します。この状態のスレッドは、実行可能なスレッドプールにあり、実行可能になり、CPUの使用権を取得するのを待っています。
(3)。実行状態:Ready StateのスレッドはCPUを取得し、プログラムコードを実行します。
(4)。ブロック状態:ブロックされた状態とは、スレッドが何らかの理由でCPUの使用権を放棄し、一時的に実行を停止することを意味します。スレッドが準備が整った状態に入るまで、実行中の状態に行く機会がありません。閉塞には3つのタイプがあります。
- ブロックを待つ:実行中のスレッドはwait()メソッドを実行し、JVMはスレッドを待機プールに入れます。
- 同期ブロッキング:実行スレッドがオブジェクトの同期ロックを取得すると、同期ロックが他のスレッドで占有されている場合、JVMはスレッドをロックプールに入れます。
- その他のブロッキング:実行中のスレッドがSleep()またはJoin()メソッドを実行するか、I/O要求を発行する場合、JVMはスレッドをブロッキング状態に設定します。 Sleep()状態がタイムアウトしたとき、Join()がスレッドが終了またはタイミングアウトするのを待っているか、I/O処理が完了した場合、スレッドは準備ができた状態に再入力されました。
(5)。 Dead State:スレッドは、例外のために実行()メソッドの実行が終了または終了し、スレッドはライフサイクルを終了します。
5。スレッドの優先度とデーモンスレッド
1。スレッドの優先順位
Javaでは、各スレッドに優先順位があり、デフォルトでは、スレッドが親クラスの優先度を継承します。 SetPriorityメソッドを使用して、スレッドの優先順位を増加または減少させることができます。優先度は、min_priority(スレッドクラスで1として定義)とmax_priority(スレッドクラスで10として定義)の間の任意の値に設定できます。スレッドのデフォルトの優先度は、norm_priority(スレッドクラスで5と定義されています)です。
優先順位に頼らないようにしてください。本当に使用したい場合は、初心者が犯す一般的な間違いを避ける必要があります。いくつかの高優先度スレッドが非アクティブな状態に入っていない場合、低優先度のスレッドは実行されない場合があります。スケジューラが新しいスレッドを実行することを決定したときはいつでも、最初に優先順位を持ってスレッドの中から選択しますが、これは低優先度のスレッドを完全に飢えさせます。
2。デーモンスレッド
setdaemon(true)に電話してください。スレッドをデーモンスレッドに変換します。デーモンスレッドの唯一の目的は、他のスレッドにサービスを提供することです。タイミングスレッドは例です。他のスレッドに定期的に信号を送信するか、キャッシュアイテムを伝える時代遅れのスレッドをクリアします。デーモンのスレッドのみが残っている場合、仮想マシンは終了します。なぜなら、デーモンスレッドのみが残っている場合、プログラムを実行し続ける必要はないからです。
さらに、JVMのゴミコレクション、メモリ管理、その他のスレッドはデーモンスレッドです。また、データベースアプリケーションを実行する場合、使用されるデータベース接続プールには、接続の数、タイムアウト時間、ステータスなどを監視する多くの背景スレッドも含まれています。
上記は、Javaマルチスレッドのスレッド定義、状態、およびプロパティに関するものです。みんなの学習に役立つことを願っています。