マルチスレッド Java
どのアプリケーションも複数のプロセス (インスタンス) を持つことができます。この各プロセスは、単一のスレッドまたは複数のスレッドとして割り当てることができます。このチュートリアルでは、複数のタスクを同時に実行する方法と、スレッドとスレッド間の同期について詳しく説明します。
シングルスレッドとは何ですか?
単一のスレッド Java 基本的に軽量で、処理の最小単位です。 Java 「スレッドクラス」を使用してスレッドを使用します。スレッドには2つの種類があります。 ユーザースレッドとデーモンスレッド (デーモン スレッドは、アプリケーションをクリーンアップするときに使用され、バックグラウンドで使用されます)。アプリケーションが最初に起動すると、ユーザー スレッドが作成されます。その後、多くのユーザー スレッドとデーモン スレッドを作成できます。
シングルスレッドの例:
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
シングルスレッドの利点:
- システム内で単一スレッドが実行されるため、アプリケーションのオーバーヘッドが削減されます。
- また、アプリケーションのメンテナンスコストも削減されます。
マルチスレッドとは Java?
マルチスレッド in Java 2つ以上のスレッドを同時に実行してCPUを最大限に活用するプロセスです。マルチスレッドアプリケーションは2つ以上のスレッドを同時に実行します。そのため、同時実行とも呼ばれます。 Java各スレッドは互いに並行して実行されます。複数のスレッドは別々のメモリ領域を割り当てないため、メモリを節約できます。また、スレッド間のコンテキスト切り替えにかかる時間も短縮されます。
マルチスレッドの例:
package demotest; public class GuruThread1 implements Runnable { public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
マルチスレッドの利点:
- スレッドは独立しているため、ユーザーはブロックされず、一度に複数の操作を実行できます。
- そのため、スレッドは独立しているため、XNUMX つのスレッドで例外が発生した場合でも、他のスレッドは影響を受けません。
スレッドのライフサイクル Java
スレッドのライフサイクル:
上の図に示すように、スレッドのライフサイクルにはさまざまな段階があります。
- New
- 実行可能
- Running:
- 待っています
- デッド
- 新機能: このフェーズでは、クラス「スレッドクラス」を使用してスレッドが作成されます。プログラムが実行されるまでこの状態が維持されます。 開始 スレッド。 ボーンスレッドとも呼ばれます。
- 実行可能: このページでは、スレッドのインスタンスが start メソッドで呼び出されます。 スレッド制御はスケジューラに渡され、実行が終了します。 スレッドを実行するかどうかはスケジューラによって異なります。
- ランニング: スレッドが実行を開始すると、状態は「実行中」状態に変更されます。 スケジューラはスレッド プールから XNUMX つのスレッドを選択し、アプリケーションで実行を開始します。
- 待っている: これは、スレッドが待機しなければならない状態です。アプリケーションでは複数のスレッドが実行されているため、スレッド間の同期が必要です。したがって、1 つのスレッドは、他のスレッドが実行されるまで待機する必要があります。したがって、この状態は待機状態と呼ばれます。
- デッド: スレッドが終了したときの状態です。 スレッドは実行状態にあり、処理が完了するとすぐに「停止状態」になります。
マルチスレッドの手法 Java
スレッドで一般的に使用されるメソッドには、次のようなものがあります。方法 | Description |
---|---|
開始() | このメソッドはスレッドの実行を開始し、 JVM スレッド上で run() メソッドを呼び出します。 |
スリープ(int ミリ秒) | このメソッドはスレッドをスリープ状態にするため、指定された数ミリ秒間スレッドの実行が一時停止し、その後、再びスレッドの実行が開始されます。これはスレッドの同期に役立ちます。 |
getName() | スレッドの名前を返します。 |
setPriority(int newpriority) | スレッドの優先度を変更します。 |
収率 () | 現在のスレッドが停止し、他のスレッドが実行されます。 |
例: このマルチスレッドプログラムでは Java たとえば、スレッドを作成し、スレッドで使用できる組み込みメソッドを調べます。
package demotest; public class thread_example1 implements Runnable { @Override public void run() { } public static void main(String[] args) { Thread guruthread1 = new Thread(); guruthread1.start(); try { guruthread1.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } guruthread1.setPriority(1); int gurupriority = guruthread1.getPriority(); System.out.println(gurupriority); System.out.println("Thread Running"); } }
コードの説明:
- コード行 2: Runnable インターフェイスを実装するクラス「thread_Example1」を作成しています (これは、スレッドによって実行されるインスタンスを持つ任意のクラスによって実装される必要があります)。
- コード行 4: 実行可能インターフェイスの run メソッドをオーバーライドすることが必須であるため、このメソッドはそのメソッドをオーバーライドします。
- コード行 6: ここでは、スレッドの実行を開始する main メソッドを定義しました。
- コード行 7: ここでは、スレッドの新しいクラスをインスタンス化して、新しいスレッド名を「guruthread1」として作成しています。
- コード行 8: 「guruthread1」インスタンスを使用してスレッドの「start」メソッドを使用します。 ここでスレッドの実行が開始されます。
- コード行 10: ここでは、「guruthread1」インスタンスを使用するスレッドの「sleep」メソッドを使用しています。 したがって、スレッドは 1000 ミリ秒間スリープします。
- コード9-14: ここでは、チェック例外(割り込み例外)が発生するため、try catch ブロックに sleep メソッドを配置しています。
- コード行 15: ここでは、スレッドの優先順位をいずれかの優先順位から 1 に設定します。
- コード行 16: ここでは getPriority() を使用してスレッドの優先度を取得しています。
- コード行 17: ここでは getPriority から取得した値を出力しています。
- コード行 18: ここではスレッドが実行されているテキストを書いています。
上記のコードを実行すると、次の出力が得られます。
出力:
5 はスレッドの優先度で、「実行中のスレッド」はコードの出力であるテキストです。
Java スレッド Sync神化
マルチスレッドでは、プログラムの動作が非同期になります。1 つのスレッドがデータを書き込んでいるときに、別のスレッドが同時にデータを読み取っていると、アプリケーションに不整合が生じる可能性があります。2 つ以上のスレッドで共有リソースにアクセスする必要がある場合は、同期アプローチが使用されます。 Java 同期された動作を実装するための同期メソッドが提供されています。
このアプローチでは、スレッドが同期ブロック内に到達すると、他のスレッドは同じオブジェクトでそのメソッドを呼び出すことができなくなります。すべてのスレッドは、そのスレッドが同期ブロックを終了してそこから抜け出すまで待機する必要があります。このように、同期はマルチスレッド アプリケーションに役立ちます。1 つのスレッドは、他のスレッドの実行が終了するまで待機する必要があります。その後、他のスレッドの実行が許可されます。
次のような形式で記述できます。
Synchronized(object) { //Block of statements to be synchronized }
マルチスレッド Java サンプルプログラム
このマルチスレッドでは Java たとえば、2 つのスレッドを取得し、スレッドの名前を取得します。
Example1:
GuruThread1.java package demotest; public class GuruThread1 implements Runnable{ /** * @param args */ public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
コードの説明:
- コード行 3: Runnable を実装するクラス「GuruThread1」を選択しました (これは、スレッドによって実行されるインスタンスを持つ任意のクラスによって実装される必要があります)。
- コード行 8: これはクラスのメインメソッドです
- コード行 9: ここでは、Thread クラスをインスタンス化し、「guruThread1」という名前のインスタンスを作成し、スレッドを作成しています。
- コード行 10: ここでは、Thread クラスをインスタンス化し、「guruThread2」という名前のインスタンスを作成し、スレッドを作成しています。
- コード行 11: スレッド (guruThread1) を開始しています。
- コード行 12: スレッド (guruThread2) を開始しています。
- コード行 13: 「スレッド名は次のとおりです:」というテキストを出力します。
- コード行 14: スレッド クラスのメソッド getName() を使用して、スレッド 1 の名前を取得します。
- コード行 15: スレッド クラスのメソッド getName() を使用して、スレッド 2 の名前を取得します。
上記のコードを実行すると、次の出力が得られます。
出力:
ここではスレッド名が次のように出力されています
- Guru1
- Guru2
例2:
このマルチスレッドでは Java たとえば、実行可能なインターフェースの run() メソッドと start() メソッドをオーバーライドし、そのクラスの 2 つのスレッドを作成してそれに応じて実行する方法について学習します。
また、2つの授業を受講しているのですが、
- 実行可能なインターフェースを実装するものと、
- もう XNUMX つは main メソッドを持ち、それに応じて実行されます。
package demotest; public class GuruThread2 { public static void main(String[] args) { // TODO Auto-generated method stub GuruThread3 threadguru1 = new GuruThread3("guru1"); threadguru1.start(); GuruThread3 threadguru2 = new GuruThread3("guru2"); threadguru2.start(); } } class GuruThread3 implements Runnable { Thread guruthread; private String guruname; GuruThread3(String name) { guruname = name; } @Override public void run() { System.out.println("Thread running" + guruname); for (int i = 0; i < 4; i++) { System.out.println(i); System.out.println(guruname); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Thread has been interrupted"); } } } public void start() { System.out.println("Thread started"); if (guruthread == null) { guruthread = new Thread(this, guruname); guruthread.start(); } } }
コードの説明:
- コード行 2: ここでは、main メソッドを含むクラス「GuruThread2」を取り上げます。
- コード行 4: ここではクラスの main メソッドを取り上げます。
- コード行 6 ~ 7: ここでは、クラス GuruThread3 (コードの下の行で作成) のインスタンスを「threadguru1」として作成し、スレッドを開始しています。
- コード行 8 ~ 9: ここでは、GuruThread3 クラスの別のインスタンス (コードの下の行で作成されます) を「threadguru2」として作成し、スレッドを開始しています。
- コード行 11: ここでは、実行可能なインターフェイスを実装するクラス「GuruThread3」を作成しています (スレッドによって実行されるインスタンスを持つ任意のクラスによって実装される必要があります)。
- コード行 13 ~ 14: XNUMX つのクラス変数を取得し、XNUMX つはスレッド クラスの型、もう XNUMX つは文字列クラスの型です。
- コード行 15 ~ 18: GuruThread3 コンストラクターをオーバーライドしています。このコンストラクターは、クラス変数 guruname に割り当てられる文字列型 (スレッド名) として引数を XNUMX つ取り、したがってスレッドの名前が保存されます。
- コード行 20: ここでは、実行可能インターフェースの run() メソッドをオーバーライドしています。
- コード行 21: println文を使用してスレッド名を出力しています。
- コード行 22 ~ 31: ここでは、カウンターが 0 に初期化された for ループを使用しています。カウンターは 4 未満であってはなりません (任意の数値を使用できるため、ここではループは 4 回実行されます)。カウンターをインクリメントします。 スレッド名を出力し、スリープ メソッドでチェック例外が発生したため、スレッドを try-catch ブロック内で 1000 ミリ秒スリープさせます。
- コード行 33: ここでは、実行可能インターフェイスの start メソッドをオーバーライドしています。
- コード行 35: 「スレッドが開始されました」というテキストを出力しています。
- コード行 36 ~ 40: ここでは、if 条件を使用して、クラス変数 guruthread に値があるかどうかを確認しています。 null の場合、名前をパラメータ (コンストラクターで割り当てられた値) として受け取るスレッド クラスを使用してインスタンスを作成しています。 その後、start() メソッドを使用してスレッドが開始されます。
上記のコードを実行すると、次の出力が得られます。
出力:
スレッドが XNUMX つあるため、「スレッドが開始されました」というメッセージが XNUMX 回表示されます。
出力したスレッドの名前を取得します。
for ループに入り、カウンターとスレッド名が出力され、カウンターは 0 から始まります。
ループは 1000 回実行され、その間にスレッドは XNUMX ミリ秒スリープされます。
したがって、最初に guru1 を取得し、guru2 を取得し、次に guru2 を取得します。これは、スレッドがここで 1000 ミリ秒スリープしているためです。次に、次の guru1 と再び guru1 を取得し、スレッドが 1000 ミリ秒間スリープしているため、guru2 を取得し、次に guru1 を取得します。
まとめ
このチュートリアルでは、マルチスレッドアプリケーションについて見てきました。 Java シングルスレッドとマルチスレッドの使い方 Java.
- マルチスレッドを説明する Java: マルチスレッドでは、スレッドが独立しており、一度に複数の操作を実行できるため、ユーザーはブロックされません。
- スレッドのライフサイクルのさまざまな段階は、
- New
- 実行可能
- Running:
- 待っています
- デッド
- についても学びました 同期 これにより、アプリケーションがスムーズに実行されます。
- マルチスレッドプログラミング Java さらに多くのアプリケーション タスクが簡単になります。