Javaのマルチスレッドプログラミング
組み込みのサポートを提供するためのJavaマルチスレッドプログラミング。 マルチスレッドプログラムでは、並行して実行できる2つ以上の部分が含まれています。 プログラムの各部分は、スレッドと呼ばれ、各スレッドは、実行の別々のパスを定義します。
マルチスレッドは、マルチタスク、マルチスレッドの特殊な形式ですが、より小さいリソースのオーバーヘッドを使用しています。
他の用語は、本明細書で定義され、スレッド関連する - 処理:オペレーティングシステムを含むプロセスは、1つ以上のスレッドを含むメモリ空間を割り当てます。 別のスレッドが存在することはできません、それはプロセスの一部でなければなりません。 プロセスを実行するには、スレッドの終了後まで、すべての非待機の最後に実行されています。
マルチスレッドは、完全なCPU使用率の目的を達するために効率的なプログラムを書くプログラマを満たすことができます。
スレッドのライフサイクル
そのライフサイクルのすべての段階を縫います。 次の図は、スレッドの完全なライフサイクルを示しています。
- 新ステータス:
スレッドオブジェクトを作成するために、 新しいキーワードとThreadクラスまたはサブクラスを使用した後、スレッドオブジェクトは、新しい状態になっています。 これは、プログラム開始()このスレッドになるまでこの状態のままになります。
- レディ状態:
スレッドオブジェクトは、start()メソッド、準備完了状態にスレッドを呼び出すためにする場合。 レディキュー中のレディスレッドは、JVMのスレッドスケジューラのスケジュールを待ちます。
- 動作状態:
スレッドがCPUリソースの準備状態を取得する場合は、 実行を行うことができます()、スレッドは、この時点で実行されます。 最も複雑なを実行しているスレッドは、ブロックされた状態、レディ状態、および死の状態になることができます。
- ブロックされた状態:
スレッドがスリープ状態(スリープ)の後に実行された場合、サスペンド(ハング)および他の方法は、占有リソースの損失は、スレッドが実行されているから遮断状態に入ります。 睡眠時間後に再入力準備状態に機器やリソースを得るようになってきました。
- 死のステータス:
タスクのスレッドの実行状態、または他の終了条件が発生すると、スレッドは終了状態に切り替えられます。
スレッドの優先順位
各Javaスレッドは、オペレーティングシステムのスレッドスケジューリングの順序を決定する手助けとなる優先順位を有します。
10(Thread.MAX_PRIORITY) - Javaスレッドの優先順位は1(Thread.MIN_PRIORITY)の範囲の整数です。
デフォルトでは、各スレッドは、優先度NORM_PRIORITY(5)が割り当てられます。
優先度の高いスレッドは、プログラムへのより重要であり、低優先度のスレッドの前にプロセッサリソースを割り当てる必要があります。 しかし、注文は実行のスレッドの優先度のスレッドを保証し、インターネット上で非常に依存しているしません。
スレッドを作成します。
Javaはスレッドを作成するには、2つのメソッドを提供します。
- インターフェイスを実装することにより、実行可能。
- 継承Threadクラス自体を通じ。
、Runnableインタフェースを実装することによってスレッドを作成するには
スレッドを作成し、最も簡単な方法は、Runnableインタフェースを実装するクラスを作成することです。
Runnableを達成するためには、クラス、メソッド呼び出しの実行()は、次の文を実行した場合のみ必要です。
public void run()
このメソッドをオーバーライドすることができ、ラン()だけでメインスレッドのように、他の方法、他のクラスの使用を呼び出して、変数を宣言することができますを理解することが重要です。
クラスを作成することは、Runnableインタフェースを実装した後、あなたはクラスのスレッドをオブジェクトをインスタンス化することができます。
スレッドがいくつかのコンストラクタを定義して、私たちはしばしば使用これを次のとおりです。
Thread(Runnable threadOb,String threadName);
ここで、threadObは、Runnableインタフェースを実装するクラスのインスタンスである、とのthreadNameスレッドの新しい名前を指定します。
新しいスレッドが作成された後、あなたはそれが実行され、そのstart()メソッドを呼び出します。
void start();
例
ここでは、スレッドを作成しての実行を開始するために、そのインスタンスは、次のとおりです。
// 创建一个新的线程 class NewThread implements Runnable { Thread t; NewThread() { // 创建第二个新线程 t = new Thread(this, "Demo Thread"); System.out.println("Child thread: " + t); t.start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 暂停线程 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ThreadDemo { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
次のように上記のプログラムが実行されるコンパイルします。
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
継承スレッドを通してスレッドを作成するには
スレッドを作成する2番目の方法は、Threadクラスを継承する新しいクラスを作成し、クラスのインスタンスを作成することです。
継承するクラスは、新しいスレッドのエントリポイントであるrun()メソッドをオーバーライドしなければなりません。 また、start()メソッドを実行するために呼び出す必要があります。
例
// 通过继承 Thread 创建线程 class NewThread extends Thread { NewThread() { // 创建第二个新线程 super("Demo Thread"); System.out.println("Child thread: " + this); start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 让线程休眠一会 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ExtendThread { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
次のように上記のプログラムが実行されるコンパイルします。
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
スレッドのメソッド
次の表に、いくつかの重要な方法Threadクラスを示しています。
いいえ。 | メソッド説明 |
---|---|
1 | 公共ボイド開始() 実行を開始するには、このスレッドを作成し、Java仮想マシンは、このスレッドのrunメソッドを呼び出します。 |
2 | ます。public void実行() このスレッドが別個のRunnable実行オブジェクトを使用して構築された場合は、Runnableオブジェクトのrunメソッドを呼び出し、そうでない場合、このメソッドは何も行わずに復帰します。 |
3 | 公共の最終的なボイドのsetName(文字列名) 同じパラメータ名となるよう、このスレッドの名前を変更します。 |
4 | 公共の最終的なボイドsetPriorityを(int型の優先順位) スレッドの優先順位を変更します。 |
5 | 公共の最終的なボイド値はsetDaemon(上ブール) デーモンスレッドまたはユーザスレッドとしてこのスレッドをマークします。 |
6 | 公共の最終的なボイドが(長いミリ秒)に参加します ミリ秒(ミリ秒)の最大にこのスレッドを待ちます。 |
7 | 公共ボイド割り込み() スレッドを中断。 |
8 | 公共の最後のブールのIsAlive() このスレッドがアクティブである場合。 |
このスレッドがアクティブである場合。 上記の方法は、Threadオブジェクトと呼ばれています。 次のメソッドは、Threadクラスの静的メソッドです。
いいえ。 | メソッド説明 |
---|---|
1 | パブリック静的ボイド収率() 現在実行中のスレッドオブジェクトを一時停止し、他のスレッドを実行します。 |
2 | パブリック静的ボイド睡眠(長いミリ秒) 指定されたミリ秒数以内に現在の精度と正確さによって(実行を停止)、このオペレーティングシステムタイマーとスケジューラをスリープ状態にスレッドを実行します。 |
3 | パブリック静的ブールholdsLock(オブジェクトX) 現在のスレッドが指定されたオブジェクトに対するモニターロックを保持している場合にのみ場合は、trueを返します。 |
4 | パブリック静的スレッドcurrentThread() それは現在実行中のスレッドオブジェクトへの参照を返します。 |
5 | 公共の静的な無効dumpStack() 標準エラーストリームに現在のスレッドのスタックトレースを出力します。 |
例
次のプログラムは、ThreadクラスThreadClassDemo方法をいくつか示します。
// 文件名 : DisplayMessage.java // 通过实现 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); } } }
// 文件名 : GuessANumber.java // 通过继承 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.**"); } }
// 文件名 : 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 Hello Hello Hello Thread-2 guesses 27 Hello ** Correct! Thread-2 in 102 guesses.** Hello Starting thread4... Hello Hello ..........remaining result produced.
いくつかの主要な概念スレッド:
プログラミングをマルチスレッド化する場合は、次の概念を理解する必要があります。
- スレッド同期
- スレッド間通信
- スレッドのデッドロック
- スレッド制御:停止、サスペンドとレジューム
複数のスレッドを使用します
マルチスレッドプログラムを効果的に利用するための鍵は、同時実行ではなく、シリアル実行よりも理解されています。 たとえば、次のプログラムは、2つのサブシステムは、同時に使用すると、マルチスレッドプログラミングの利点を取る必要があり、この時間を実行する必要がありました。
複数のスレッドを使用することにより、あなたは非常に効率的なプログラムを書くことができます。 しかし、あなたはあまりにも多くのスレッドを作成した場合、プログラムの実行の効率が実際に強化されたのではなく、減少していることに注意してください。
コンテキストスイッチのオーバーヘッドがあなたがあまりにも多くのスレッドを作成した場合、プログラムの実行時間をコンテキスト切り替えに費やされるCPU時間は、よりになり、また非常に重要であることに注意してください!