ライフスレッド 1スレッド作成スレッドは、スレッドの開始と同じ作成しません2. 糸の3終了4. [追加のスレッド5.スケジューリング6.スリープ7.デーモンスレッドを8例:複数のスレッドを持つ大規模なタスクを因数分解9.まとめ
スレッドを作成します。 | ページ1(9ページ) |
Javaプログラム内のスレッドを作成する方法はいくつかあります。プライマリスレッド:各Javaプログラムには、少なくとも1つのスレッドが含まれています。他のスレッドはでありThread
、コンストラクタまたはクラスのインスタンスは、継承Thread
を作成するクラスを。
Javaスレッドを直接インスタンス化することができますThread
継承のオブジェクトまたはインスタンスThread
他のスレッドを作成するオブジェクトを。では、スレッドの基礎(私たちは10秒以内にできるだけ多くの素数を計算)の例では、我々は、インスタンス化することによっているCalculatePrimes
(それが継承するオブジェクトの種類をThread
)、私はスレッドを作成しました。
私たちが議論するとJavaプログラムのスレッドは、関連する2つのエンティティを参照することがあります。に代わって行われた作業の実際のスレッドまたはスレッドThread
オブジェクトを。実行中のスレッドは、通常、オペレーティングシステムによって作成され、Thread
オブジェクトは、関連するスレッドを制御する方法として、JavaのVMによって作成されます。
スレッドを作成し、スレッドが同じではありません開始 | 2ページ(9ページ) |
スレッドに新しいスレッドでThread
オブジェクト呼び出しをstart()
メソッドの前に、この新しいスレッドは本当に開始されていません。Thread
それは本当に始めたスレッドの前にオブジェクトが存在していて、まだそのスレッドが終了した後に存在しています。これは、スレッドが開始されていないか、完了している場合でも、あなたがコントロールまたはスレッドが作成された情報を得ることができます。
通常、コンストラクタでstart()
スレッドを開始するのは良い考えではありません。そうすることで、対象物は、部分的に構築し、新しいスレッドにさらされることになります。オブジェクトがスレッドを持っている場合、それはスタートアップそのスレッド提供しなければならないstart()
かinit()
の方法を、というよりも、コンストラクタからそれを開始します。(参照リソースの記事は、この概念のより詳細な説明へのリンクを提供し得ること。)
スレッドの終了 | ページ3(合計9) |
スレッドには、3つの方法のいずれかで終了します。
- スレッドは、その到達した
run()
最終的なアプローチを。 - スレッドはキャッチされないスロー
Exception
かをError
。 - 別のスレッドが推奨されない呼び出す
stop()
方法を。見捨てられた、まだ存在していますが、新しいコードでそれらを使用しないでください、そして既存のコードからそれらを削除しようとする必要があり、これらの方法を指します。
Javaプログラム内のすべてのスレッドが完了すると、プログラムが終了します。
スレッドに参加 | ページ4(合計9) |
:スレッドのAPIが完了するまで他のスレッドを待つ方法が含まれているjoin()
方法を。呼び出すときにThread.join()
ターゲットスレッドが完了するまで、呼び出し元のスレッドがブロックされます。
Thread.join()
多くの場合、小さな問題の数に大きな問題であることをスレッドを使用するプログラムによって使用される、小さな問題は、それぞれのスレッドが割り当てられます。10個のスレッドを作成するには、この章の終わりの例として、そして、それらを起動しThread.join()
、それらが完了するのを待ちます。
派遣 | ページ5(合計9) |
使用する場合を除きThread.join()
とObject.wait()
外部、スレッドのスケジューリングと実行タイミングは不明です。2つのスレッドが同時に実行すると、待っていない場合は、任意の2つの命令の間、他のスレッドが実行され、プログラム変数を変更することができることを前提としなければなりません。他のスレッドがアクセスするスレッドの変数を見ることができれば、静的フィールド(グローバル変数)からデータを直接または間接的に参照されるような、データの一貫性を保証するために同期化を使用しなければなりません。
次の簡単な例では、我々は、2つの行を印刷するために、各スレッドを二つのスレッドを作成して開始しますSystem.out
:
public class TwoThreads {
public static class Thread1 extends Thread {
public void run() {
System.out.println("A");
System.out.println("B");
}
}
public static class Thread2 extends Thread {
public void run() {
System.out.println("1");
System.out.println("2");
}
}
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
}
私たちは、これらの行を実行するどのような順番で知らない、ただ「1」、「2」は、印刷する前に、だけでなく、「」あなたは「B」を印刷していることを知っています。出力は以下の結果のいずれであってもよいです。
- 1 2 AB
- 1 A 2 B
- 1 AB 2
- 1 2 B
- 1件のB 2
- AB 1 2
だけでなく、結果が異なるマシン間で異なっていてもよく、同じプログラムの複数の実行は、同じマシン上で異なる結果を生成することがあります。あなたは、実行の特定の順序を強制的に同期を使用していない限り、スレッドは、別のスレッドの前にいくつかのアクションを実行すると仮定してはいけません。
休眠 | ページ6(9ページ) |
スレッドAPIは、sleep()
それが時間の指定した期間後または現在のスレッドの他のスレッドまでまで待ち状態に現在のスレッドを作成し、メソッドをThread
呼び出すためのオブジェクトThread.interrupt()
、それによってスレッドを中断し、。期間を指定した後、スレッドが実行可能になっ回し、および実行可能スレッドのスケジューラキューに戻ります。
スレッドがする場合Thread.interrupt()
に中断を呼び出し、その後、スレッドは休眠スローされますInterruptedException
ので、スレッドがウェイクアップ割り込みであることを知っているだろう、あなたはタイマーが満了しているかどうかを確認する必要はありません。
Thread.yield()
以下のような方法Thread.sleep()
と同じですが、睡眠を引き起こすが、一瞬だけのために、他のスレッドが実行できるように、現在のスレッドを中断しません。優先度の高いスレッドが呼び出したときにほとんどの実装ではThread.yield()
、優先順位の低いスレッドが実行されません。
CalculatePrimes
例では、素数を計算するバックグラウンドスレッドを使用し、その後、10秒睡眠。タイマーの期限が切れると、それはフラグを設定します、それは10秒となっていたと述べました。
デーモンスレッド | 7ページ(合計9) |
私たちは、すべてのスレッドのJavaプログラムが完了すると、プログラムが終了することを述べたが、これは完全に正しいではありません。このようガベージコレクションのスレッドとJVMによって作成された他のスレッドとして隠しシステムスレッドは、何が起こるのだろうか?私たちは、これらのスレッドを停止する方法がありません。これらのスレッドが行うJavaプログラムを終了する方法を実行している場合は?
呼ばれるシステムスレッドデーモンスレッド。それは実際にはすべての非デーモンスレッド完全撤退した後のJavaプログラム。
任意のスレッドがデーモンスレッドになることができます。呼び出すことにより、Thread.setDaemon()
スレッドを示すために、デーモンスレッド方式です。あなたは、イベントスレッドは、これらのスレッドが有用であることが、他の非デーモンスレッドが実行されている場合にのみ、そのようなタイマースレッドまたは他の遅延と、プログラムでスレッドを作成するために、バックグラウンドのデーモンスレッドとして使用することもできます。
例:複数のスレッドを持つ大規模なタスクを打破 | 8ページ(合計9) |
この例では、TenThreads
それは、各スレッドは、ジョブの一部を実行し、10スレッドプログラムが作成示します。プログラムが終了し、すべてのスレッドを待ち、その後、結果を収集します。
/**
* Creates ten threads to search for the maximum value of a large matrix.
* Each thread searches one portion of the matrix.
*/
public class TenThreads {
private static class WorkerThread extends Thread {
int max = Integer.MIN_VALUE;
int[] ourArray;
public WorkerThread(int[] ourArray) {
this.ourArray = ourArray;
}
// Find the maximum value in our particular piece of the array
public void run() {
for (int i = 0; i < ourArray.length; i++)
max = Math.max(max, ourArray[i]);
}
public int getMax() {
return max;
}
}
public static void main(String[] args) {
WorkerThread[] threads = new WorkerThread[10];
int[][] bigMatrix = getBigHairyMatrix();
int max = Integer.MIN_VALUE;
// Give each thread a slice of the matrix to work with
for (int i=0; i < 10; i++) {
threads[i] = new WorkerThread(bigMatrix[i]);
threads[i].start();
}
// Wait for each thread to finish
try {
for (int i=0; i < 10; i++) {
threads[i].join();
max = Math.max(max, threads[i].getMax());
}
}
catch (InterruptedException e) {
// fall through
}
System.out.println("Maximum value was " + max);
}
}
小结第 9 页(共9 页)
就象程序一样,线程有生命周期:它们启动、执行,然后完成。一个程序或进程也许包含多个线程,而这些线程看来互相单独地执行。
线程是通过实例化
Thread
对象或实例化继承 Thread
的对象来创建的,但在对新的 Thread
对象调用 start()
方法之前,这个线程并没有开始执行。当线程运行到其 run()
方法的末尾或抛出未经处理的异常时,它们就结束了。
sleep()
方法可以用于等待一段特定时间;而 join()
方法可能用于等到另一个线程完成。
ます。https://www.cnblogs.com/licheng/archive/2008/09/23/1296804.htmlで再現