Java-マルチスレッド
Java は マルチスレッド プログラミング言語 これは、Java を使用してマルチスレッド プログラムを開発できることを意味します。マルチスレッド プログラムには、同時に実行できる 2 つ以上の部分が含まれており、特にコンピューターに複数の CPU がある場合に、各部分が同時に異なるタスクを処理して、利用可能なリソースを最適に利用できます。
定義上、マルチタスクとは、複数のプロセスが CPU などの共通の処理リソースを共有することです。マルチスレッドは、マルチタスクの概念をアプリケーションに拡張したもので、単一アプリケーション内の特定の操作を個々のスレッドに細分化できます。各スレッドは並行して実行できます。 OS は、異なるアプリケーション間だけでなく、アプリケーション内の各スレッド間でも処理時間を分割します。
マルチスレッドを使用すると、同じプログラムで複数のアクティビティを同時に処理できるように記述できます。
スレッドのライフサイクル
スレッドは、そのライフ サイクルのさまざまな段階を経ます。たとえば、スレッドは誕生、開始、実行、終了します。次の図は、スレッドの完全なライフ サイクルを示しています。
以下は、ライフサイクルの段階です-
- <リ>
新規 - 新しいスレッドは、新しい状態でライフサイクルを開始します。プログラムがスレッドを開始するまで、この状態のままです。 生まれたスレッドとも呼ばれます .
<リ>実行可能 − 新しく生まれたスレッドが開始されると、そのスレッドは実行可能になります。この状態のスレッドは、そのタスクを実行していると見なされます。
<リ>待っています - スレッドが別のスレッドがタスクを実行するのを待っている間に、スレッドが待機状態に移行することがあります。スレッドは、別のスレッドが待機中のスレッドに実行の継続を通知した場合にのみ、実行可能な状態に戻ります。
<リ>時限待機 - 実行可能なスレッドは、指定された時間間隔で時限待機状態に入ることができます。この状態のスレッドは、その時間間隔が満了するか、待機しているイベントが発生すると、実行可能な状態に戻ります。
<リ>終了(死亡) − 実行可能なスレッドは、タスクを完了するか終了すると終了状態になります。
スレッドの優先度
すべての Java スレッドには、オペレーティング システムがスレッドをスケジュールする順序を決定するのに役立つ優先度があります。
Java スレッドの優先順位は、MIN_PRIORITY (定数 1) から MAX_PRIORITY (定数 10) の範囲です。デフォルトでは、すべてのスレッドに NORM_PRIORITY (定数 5) の優先度が与えられます。
優先順位の高いスレッドはプログラムにとってより重要であり、優先順位の低いスレッドよりも前にプロセッサ時間を割り当てる必要があります。ただし、スレッドの優先度はスレッドの実行順序を保証できず、プラットフォームに大きく依存します。
実行可能なインターフェイスを実装してスレッドを作成する
クラスがスレッドとして実行されることを意図している場合は、Runnable を実装することでこれを実現できます。 インターフェース。 3 つの基本的な手順に従う必要があります −
ステップ 1
最初のステップとして、Runnable によって提供される run() メソッドを実装する必要があります。 インターフェース。このメソッドはスレッドのエントリ ポイントを提供し、完全なビジネス ロジックをこのメソッド内に配置します。以下は、run() メソッドの簡単な構文です −
public void run( )
ステップ 2
2 番目のステップとして、スレッド をインスタンス化します。 次のコンストラクターを使用したオブジェクト −
Thread(Runnable threadObj, String threadName);
ここで、threadObj Runnable を実装するクラスのインスタンスです インターフェイスと threadName 新しいスレッドに付けられた名前です。
ステップ 3
Thread オブジェクトが作成されたら、start() を呼び出して開始できます。 run( ) メソッドの呼び出しを実行します。以下は、start() メソッドの簡単な構文です −
void start();
例
新しいスレッドを作成して実行を開始する例を次に示します −
ライブデモ
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
これにより、次の結果が生成されます-
出力
Creating Thread-1 Starting Thread-1 Creating Thread-2 Starting Thread-2 Running Thread-1 Thread: Thread-1, 4 Running Thread-2 Thread: Thread-2, 4 Thread: Thread-1, 3 Thread: Thread-2, 3 Thread: Thread-1, 2 Thread: Thread-2, 2 Thread: Thread-1, 1 Thread: Thread-2, 1 Thread Thread-1 exiting. Thread Thread-2 exiting.
スレッド クラスを拡張してスレッドを作成する
スレッドを作成する 2 つ目の方法は、Thread を拡張する新しいクラスを作成することです。 次の 2 つの簡単な手順を使用してクラスを作成します。このアプローチにより、Thread クラスで使用可能なメソッドを使用して作成された複数のスレッドをより柔軟に処理できます。
ステップ 1
run( ) をオーバーライドする必要があります Thread クラスで使用可能なメソッド。このメソッドはスレッドのエントリ ポイントを提供し、完全なビジネス ロジックをこのメソッド内に配置します。以下は、run() メソッドの簡単な構文です −
public void run( )
ステップ 2
Thread オブジェクトが作成されたら、start() を呼び出して開始できます。 run( ) メソッドの呼び出しを実行します。以下は、start() メソッドの簡単な構文です −
void start( );
例
これは、スレッドを拡張するために書き直された前のプログラムです −
ライブデモ
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
これにより、次の結果が生成されます-
出力
Creating Thread-1 Starting Thread-1 Creating Thread-2 Starting Thread-2 Running Thread-1 Thread: Thread-1, 4 Running Thread-2 Thread: Thread-2, 4 Thread: Thread-1, 3 Thread: Thread-2, 3 Thread: Thread-1, 2 Thread: Thread-2, 2 Thread: Thread-1, 1 Thread: Thread-2, 1 Thread Thread-1 exiting. Thread Thread-2 exiting.
スレッド メソッド
以下は、Thread クラスで使用できる重要なメソッドのリストです。
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public void start() 別の実行パスでスレッドを開始し、この Thread オブジェクトで run() メソッドを呼び出します。 |
| 2 | public void run() この Thread オブジェクトが別の Runnable ターゲットを使用してインスタンス化された場合、その Runnable オブジェクトで run() メソッドが呼び出されます。 |
| 3 | public final void setName(文字列名) Thread オブジェクトの名前を変更します。名前を取得するための getName() メソッドもあります。 |
| 4 | public final void setPriority(int 優先度) この Thread オブジェクトの優先度を設定します。可能な値は 1 から 10 の間です。 |
| 5 | public final void setDaemon(boolean on) true のパラメーターは、このスレッドがデーモン スレッドであることを示します。 |
| 6 | public final void join(長いミリ秒) 現在のスレッドが 2 番目のスレッドでこのメソッドを呼び出すと、2 番目のスレッドが終了するか、指定されたミリ秒数が経過するまで、現在のスレッドがブロックされます。 |
| 7 | public void interrupt() このスレッドを中断し、何らかの理由でブロックされた場合に実行を継続します。 |
| 8 | public final boolean isAlive() スレッドが開始されてから完了まで実行される前の時点で、スレッドが生きている場合は true を返します。 |
前のメソッドは、特定の Thread オブジェクトで呼び出されます。 Thread クラスの次のメソッドは静的です。静的メソッドの 1 つを呼び出すと、現在実行中のスレッドで操作が実行されます。
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public static void yield() 現在実行中のスレッドを、スケジュールされるのを待っている同じ優先度の他のスレッドに譲ります。 |
| 2 | public static void sleep(長いミリ秒) 少なくとも指定されたミリ秒数の間、現在実行中のスレッドをブロックさせます。 |
| 3 | public static boolean holdLock(Object x) 現在のスレッドが指定されたオブジェクトのロックを保持している場合は true を返します。 |
| 4 | public static Thread currentThread() このメソッドを呼び出すスレッドである、現在実行中のスレッドへの参照を返します。 |
| 5 | public static void dumpStack() 現在実行中のスレッドのスタック トレースを出力します。これは、マルチスレッド アプリケーションをデバッグするときに役立ちます。 |
例
次の ThreadClassDemo プログラムは、Thread クラスのこれらのメソッドのいくつかを示しています。クラス DisplayMessage を検討してください Runnable を実装する −
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
public class DisplayMessage implements Runnable {
private String message;
public DisplayMessage(String message) {
this.message = message;
}
public void run() {
while(true) {
System.out.println(message);
}
}
}
以下は、Thread クラスを拡張する別のクラスです −
// File Name : GuessANumber.java
// Create a thread to extentd Thread
public class GuessANumber extends Thread {
private int number;
public GuessANumber(int number) {
this.number = number;
}
public void run() {
int counter = 0;
int guess = 0;
do {
guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName() + " guesses " + guess);
counter++;
} while(guess != number);
System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
}
}
以下は、上記で定義されたクラスを利用するメインプログラムです-
// File Name : ThreadClassDemo.java
public class ThreadClassDemo {
public static void main(String [] args) {
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try {
thread3.join();
} catch (InterruptedException e) {
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
これにより、次の結果が生成されます。この例を何度も試すことができ、毎回異なる結果が得られます。
出力
Starting hello thread... Starting goodbye thread... Hello Hello Hello Hello Hello Hello Goodbye Goodbye Goodbye Goodbye Goodbye .......
主な Java マルチスレッドの概念
Java でマルチスレッド プログラミングを行う場合、次の概念が非常に便利である必要があります −
- <リ>
スレッド同期とは?
<リ>スレッド間通信の処理
<リ>スレッドのデッドロックの処理
<リ>主なスレッド操作
Java