Java並行プログラミング: Threadクラスの使用
以下はこの記事の目次の概要です:
1. スレッドのステータス
2. コンテキストの切り替え
3. Thread クラスのメソッド
転載元:
1. スレッドのステータス
スレッドは、作成から最終的な消滅まで、いくつかの状態を経ます。一般的に、スレッドには次の状態が含まれます: 作成 (新規)、準備完了 (実行可能)、実行中 (実行中)、ブロック済み (ブロック済み)、待機時間、待機中、および停止 (デッド)。
下の図は、スレッドの作成から消滅までの状態を示しています:
一部のチュートリアルでは、ブロック、待機、時間待機を総称してブロック状態と呼びます。ただし、ここではスレッドのステータスを Java のメソッド呼び出しとリンクさせたいので、待機と時間待機の 2 つの状態を分離します。
2. コンテキストの切り替え
シングルコア CPU (マルチコア CPU の場合、これは 1 つのコアとして理解されます) の場合、CPU は一度に 1 つのスレッドのみを実行できます。1 つのスレッドを実行すると、別のスレッドの実行に切り替わります。スレッド。これはスレッド コンテキストの切り替えと呼ばれます (プロセスについても同様です)。
3. Thread クラスのメソッド
java.lang.Thread クラスのソース コードを見ると、次のことがわかります。
Thread クラスは、Runnable インターフェイスを実装しています。 Thread クラスには、Thread の名前を表すいくつかの重要な属性があります。Priority はスレッドの優先度を表します。 10、最小値は 1、デフォルト値は 5)。デーモンはスレッドがデーモン スレッドであるかどうかを表し、ターゲットは実行されるタスクを示します。
以下は Thread クラスで一般的に使用されるメソッドです:
以下はスレッドの実行ステータスに関連するいくつかのメソッドです:
1) start メソッド
Start() はスレッドを開始するために使用されます。 start メソッドが呼び出されると、システムはユーザー定義のサブタスクを実行するために新しいスレッドを開き、このプロセスで必要なリソースが対応するスレッドに割り当てられます。
2) run メソッド
start メソッドを通じてスレッドが開始されると、スレッドは CPU 実行時間を取得するときに run メソッド本体に入り、特定の処理を実行します。タスク。 Thread クラスを継承する場合は、run メソッドをオーバーライドし、run メソッドで実行される特定のタスクを定義する必要があることに注意してください。
3) sleep メソッド
sleep メソッドには 2 つのオーバーロードされたバージョンがあります:
1
2
3
|
sleep(long millis ) / /パラメータはミリ秒です
sleep(long millis,int nanoseconds) //最初のパラメータはミリ秒、2 番目のパラメータはナノ秒です
|
スリープは、スレッドをスリープさせ、CPU を渡し、CPU に他のタスクを実行させることと同じです。
しかし、注意すべき点は、sleep メソッドはロックを解放しないということです。つまり、現在のスレッドがオブジェクトのロックを保持している場合、sleep メソッドが解放されていても、他のスレッドはそのオブジェクトにアクセスできなくなります。と呼ばれた。次の例を見ると明らかです:
1
2
3
4
5
6
7
8 9
10
11
12
13
14
15
16
17
18
19
20
21
2 2
23
24
25
26 27
28
29
30
31
32
33
|
public class Test {
オブジェクト object = new Object() ;
public static void main(String[] args) throws IOException thread1. public void run() {
System.out.println("i: 「+i); System.out.println(" ; Thread.currentThread().sleep(10000); System.out.println("Thread"+Thread.currentThread().getName ()+ "睡眠が終了します"); 出力結果:
上記の出力結果から、Thread-0がスリープ状態になると、Thread-1は特定のタスクを実行しないことがわかります。 Thread-0 が実行を完了し、Thread-0 がオブジェクト ロックを解放した場合にのみ、Thread-1 が実行を開始します。
sleepメソッドが呼び出された場合、InterruptedExceptionをキャッチするか、上位層にスローする必要があることに注意してください。スレッドのスリープ時間が経過しても、その時点で CPU が他のタスクを実行している可能性があるため、スレッドがすぐに実行されない場合があります。したがって、sleep メソッドを呼び出すことは、スレッドをブロッキング状態にすることと同じです。
4) yield メソッド
yield メソッドを呼び出すと、現在のスレッドに CPU 権限が渡され、CPU が他のスレッドを実行できるようになります。これはスリープ方法に似ており、ロックは解除されません。ただし、yield は CPU を引き渡す特定の時間を制御できません。また、yield メソッドでは、同じ優先順位を持つスレッドにのみ CPU 実行時間を取得する機会が与えられます。
スリープメソッドとは異なり、yield メソッドを呼び出すとスレッドがブロッキング状態になるのではなく、CPU 実行時間が再取得されるのを待つだけでスレッドが準備完了状態に戻ることに注意してください。
5) joinメソッド
joinメソッドには3つのオーバーロードバージョンがあります:
1
2
3
|
join() join(ロングミリス) //パラメータはミリ秒です
join(long millis,int nanoseconds) //最初のパラメータはミリ秒、2番目のパラメータはナノ秒です
|
メインスレッドで thread.join メソッドが呼び出された場合、メインメソッドはスレッドの実行が完了するまで待機するか、一定時間待機します。パラメータのない join メソッドが呼び出された場合は、スレッドの実行が完了するまで待機します。 time パラメータが指定された join メソッドが呼び出された場合は、特定のイベントが発生するまで待機します。
次の例を見てください:
1
2
3
4
5
6
7 8
9
10
11 121314151617181920212223 24252627 28 2930
|
パブリッククラステスト{ use ’s ’ using ’s ’s ‐ ‐ ‐ ); Test test = new System.out.println("スレッド" +Thread.currentThread().getName()+"wait"); class MyThread extends Thread{ public void run() { } catch (InterruptedException e) {
例外処理 }
}
}
出力結果:
thread1.join() メソッドが呼び出されると、メインスレッドは待機し、thread1 の実行が完了するまで待ってから続行することがわかります。
実際に join メソッドを呼び出すと、Object の wait メソッドが呼び出されます。これは、ソース コードを見るとわかります。
wait メソッドは、スレッドをブロック状態にし、によって占有されているロックを解放します。スレッドを削除し、CPU 実行許可を渡します。
wait メソッドはスレッドにオブジェクトのロックを解放させるため、join メソッドもスレッドにオブジェクトに保持されているロックを解放させます。 waitメソッドの具体的な使い方は以下の記事で解説しています。
6) Interruptメソッド
interruptとは、その名の通り中断を意味します。割り込みメソッドを単独で呼び出すと、ブロック状態のスレッドが例外をスローする可能性があります。つまり、割り込みメソッドと isInterrupted() メソッドは、ブロック状態のスレッドを中断するために使用されます。実行中のスレッド。
以下の例を見てください:
1
2
3
4
5
6
7 8
9
10
11 121314151617181920212223 24252627 28パブリッククラステスト{
|
start();}} swreat.interrupt(); .out.println(「スリープステータス」); 出力結果:
ここからわかるように、interruptメソッドを使用してブロック状態のスレッドに割り込みを行うことができます。では、非ブロッキング状態のスレッドは中断できるのでしょうか?この例を見てください。 9
10
11
12
131415161718192021222324 25
パブリッククラステスト{ public static void main(string [] args)trains {swreat.currentthread()sleep(2000); }}
このプログラムを実行すると、変数 i の値が Integer.MAX_VALUE を超えるまで while ループが実行され続けることがわかります。したがって、interrupt メソッドを直接呼び出しても、実行中のスレッドを中断することはできません。
ただし、isInterrupted()を使用して実行中のスレッドを中断できる場合は、interruptメソッドの呼び出しは割り込みフラグをtrueに設定することと同じであるため、isInterrupted()を呼び出して割り込みが発生したかどうかを判断することでスレッドの実行を中断できます。フラグが設定されます。たとえば、次のコード:
1
2
3
4
5
6
7
8 9
10
11 2 4
25
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new読む();
thread.start();
試してみる);
}
class MyThread extends Thread{
@Override V Public void run () {
| int i = 0;
while (! Isinterrupted () && i & lt; integer.max_value) {
system.out.println (i+"while サイクル")
Run を実行すると、いくつかの値を出力した後、while ループが出力を停止することがわかります。
ただし、この方法でスレッドを中断することは一般的に推奨されません。一般に、while ループを終了するかどうかをマークする属性 isStop が MyThread クラスに追加され、isStop の値が while ループ内で決定されます。
123456789 10111213 14
classmythreadはスレッドを拡張します{private private volatile boolean isstop = false; その後、外部で setStop メソッドを呼び出すことで while ループを終了できます。
7) stopメソッド
stopメソッドは放棄されたメソッドであり、安全ではないメソッドです。 stop メソッドを呼び出すと run メソッドの呼び出しが直接終了し、スレッドがオブジェクト ロックを保持している場合は ThreadDeath エラーがスローされるため、ロックは完全に解放され、オブジェクトのステータスが不整合になります。したがって、停止方式は基本的には使用しません。
8) destroyメソッド
destroyメソッドも放棄されたメソッドです。基本的には使用しません。
以下はスレッド属性に関連するいくつかのメソッドです:
1) getId
スレッドIDの取得に使用します
2) getNameとsetName
スレッド名の取得または設定に使用します。
3) getPriority と setPriority
スレッド優先度の取得と設定に使用されます。
4) setDaemon と isDaemon
は、スレッドがデーモンスレッドになるかどうかの設定と、スレッドがデーモンスレッドであるかどうかを判断するために使用されます。
デーモンスレッドとユーザースレッドの違いは、デーモンスレッドはそれを作成したスレッドに依存するのに対し、ユーザースレッドは依存しないことです。簡単な例を挙げると、メイン スレッドでデーモン スレッドが作成された場合、メイン メソッドの実行が終了すると、デーモン スレッドも終了します。ユーザー スレッドは完了するまで実行され続けます。 JVM では、ガベージ コレクター スレッドはデーモン スレッドです。
Threadクラスには、現在のスレッドを取得するためによく使用される静的メソッドcurrentThread()があります。
Threadクラスのメソッドのほとんどは上で説明しましたが、Threadクラスのメソッド呼び出しはスレッドの状態にどのような変化を引き起こすのでしょうか?次の写真は、上の写真を改良したものです:
|
|
|
|
|
以上がJava 並行プログラミング: Thread クラスの使用方法?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。