1、スレッドとプロセスとの間の差
プロセスは、すべてのスレッドの組であり、各スレッドは、実行プロセスのパスです。
例:Windowsのタスクマネージャのリストを見ることで、私たちはプロセスとして理解メモリ内のexeファイルを実行することができ、プロセスは、オペレーティングシステムの管理によって運営の基本単位です。
2.なぜマルチスレッドを使うのか?
主にマルチスレッドプログラムでの効率を向上させるが、パフォーマンスを向上させることができるようになりますマルチスレッドを使用しないように注意を払う必要がありますが、いくつかのケースでは、パフォーマンスが低下する可能性があります。
マルチスレッドアプリケーションのシナリオ:
2.1、目詰まりを避けるために、
私たちは、シングルスレッドでは、コードが順次実行される閉塞が操作の前に発生した場合、それはバックの動作に影響を与えるだろう、この時間は、複数のスレッドを使用することができ、非同期呼び出しとして理解することができることを知って、実際には、AJAXのフロントエンドを良い例があり、デフォルトのAjaxの非同期でオンになって、現在のページの正常な動作をブロックせずに新しいスレッドを起動するブラウザを呼び出すときに、
アイドルCPUを回避するために2.2、
例へのHTTPサーバは、HTTPリクエスト、処理され、要求に応じてのみ、単一のスレッド場合、プロセスの要求は、その後、CPUの実行のアイドル時間がたくさんあります。
多くの場合、RPCに関連する要求、データベースアクセス、ディスクIOや他の操作、遅い多くのCPUよりも、これらの操作の速度、応答を待っている間に、CPUが、新しい要求に対処するためではないので、上のhttpサーバのパフォーマンスを処理するため、貧しいです;
多くのように併存するので、多くのWebコンテナ、待機時間がAの要求のIO操作を待つように、方法に応じて、各要求に対して新しいスレッドを作成するために使用されている、我々はプロセスを継続することができますBを要求し、応答性。
作成するための3、マルチスレッド2つの一般的な方法
3.1、継承Threadクラスは、runメソッドをオーバーライドします
/**
* author: niceyoo
* blog: https://cnblogs.com/niceyoo
* desc:
*/
public class ThreadDemo {
public static void main(String[] args) {
System.out.println("-----多线程创建开始-----");
/* 1.创建一个线程*/
CreateThread createThread = new CreateThread();
/* 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法*/
System.out.println("-----多线程创建启动-----");
createThread.start();
System.out.println("-----多线程创建结束-----");
}
}
class CreateThread extends Thread {
/*run方法中编写 多线程需要执行的代码*/
@Override
public void run() {
for (int i = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
印刷結果:
-----多线程创建开始-----
-----多线程创建启动-----
-----多线程创建结束-----
i:0
i:1
i:2
i:3
i:4
i:5
i:6
i:7
i:8
i:9
スレッドの呼び出しは()メソッドを起動した後、コードは上から下に実行されますが、新しい行政府がありますされていません。
注意:ペイントデモは、異なる実行パスをマルチスレッド。
3.2、、Runnableインタフェースを実現するために、runメソッドをオーバーライドします
/**
* author: niceyoo
* blog: https://cnblogs.com/niceyoo
* desc:
*/
class CreateRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
System.out.println("-----多线程创建开始-----");
/* 1.创建一个线程 */
CreateRunnable createThread = new CreateRunnable();
/* 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法 */
System.out.println("-----多线程创建启动-----");
Thread thread = new Thread(createThread);
thread.start();
System.out.println("-----多线程创建结束-----");
}
}
印刷結果:
-----多线程创建开始-----
-----多线程创建启动-----
-----多线程创建结束-----
i:0
i:1
i:2
i:3
i:4
i:5
i:6
i:7
i:8
i:9
優れた実装継承Threadクラスや、Runnableインタフェースを使用していますか?
スケーラビリティの継承が強くないクラス継承のThreadクラスが他方を継承することができない場合はまあそれは、Runnableインタフェースを実装して、Javaの合計は、単一継承をサポートしています。
4、デーモンスレッド
二つのスレッドがありJAVA、1は、1つのスレッドの守護者である、ユーザー・スレッドです。
-
ユーザースレッド:カスタム作成からスレッドは、メインスレッドは、停止するユーザスレッドを停止しません。
-
デーモンスレッド:現在のプロセスが存在しないか、メインスレッドを停止しない、デーモンが停止されます。
どのようにデーモンスレッドを使用するには?
ただ、デーモンスレッドを設定するためには、setdaemon(true)メソッドを呼び出します。
/**
* author: niceyoo
* blog: https://cnblogs.com/niceyoo
* desc:
*/
public class DaemonThread {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
System.out.println("我是子线程...");
}
}
});
thread.setDaemon(true);
thread.start();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
System.out.println("我是主线程");
}
System.out.println("主线程执行完毕!");
}
}
結果:
...
我是主线程
我是子线程...
我是主线程
主线程执行完毕!
ランニングからの結果を参照してください、主な機能は以上実行され、続くデーモンスレッドが停止しました。
図5に示すように、マルチスレッド動作状態
常に5つの状態以下のいずれかで、最後まで実行されているから、スレッドを作成します。
新しい状態、レディ状態、状態を実行している状態と死の状態を遮断します。
5.1、新しい状態
スレッドがnew演算子を使用して作成された場合、新しいThread®は、例えば、スレッドは、この場合、新たなスレッド状態で、実行するために開始されていません。スレッドは、新生状態、まだ実行中のスレッドを開始していないプログラムコードである場合には
5.2、レディ状態
新しいスレッドが作成されたスレッドはstart()メソッドを呼び出す必要があり、スレッドを実行するために、自動的に起動しません。あるスレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出すとき、start()メソッドを実行しているシステムリソースのスレッドを作成し、スケジュールのスレッドで実行run()メソッド。start()メソッドが戻った後、スレッドが準備完了状態にあります。
彼らは唯一の実行中のスレッドを得ることができます前に、必ずすぐに実行()メソッドを実行していない態勢の状態をスレッド、スレッドはまた、他のスレッドのCPU時間とCPU時間を競争しなければなりません。コンピュータシステム内の単一のCPUが、それは同時に複数のスレッドを実行することは不可能であるため、1時間だけのスレッドが実行されています。したがって、この時点で、レディ状態にある複数のスレッドがあるかもしれません。レディ状態にある複数のスレッドのシステムをスケジュールするためにJavaスレッドスケジューラ(スレッドスケジューラ)によって運営されています。
5.3、動作状態
それは、運転に入った前にスレッドが、CPU時間を取得すると、本当に()メソッドを実行し始めました。
5.4、ブロックされた状態
スレッド実行中のプロセスは、それがブロックされた状態に様々な理由に起因することがあります。
- 睡眠メソッドを呼び出すことにより、スリープ状態にスレッド。
- I / O操作でブロックされたスレッドの呼び出し、すなわち動作が呼び出し元に戻らない出力動作に入る前に完了されます。
- スレッドがロックを取得しようとしているが、ロックが別のスレッドによって保持されています。
- スレッドは、トリガ条件を待っています。
5.5、死の状態
なぜスレッド死2つの理由があります。
- runメソッドが正常に終了し、自然死、
- キャッチされない例外は、スレッドのrunメソッド突然死を終了します。
生きている現在のスレッドかどうかを決定するために(すなわち、いずれかが実行されるかブロックされる)のisAlive()メソッドを使用します。あなたが実行しているか、ブロックされている場合は、trueを返します。スレッドはまだ新しく、状態を実行していない、またはスレッドの死は、偽が返された場合。
アクション6、join()メソッド
マルチスレッドCPUは弟、優先順位が高いほど、より自然なメリットが得られた約特に懸念しているかどうか、また、いわゆる優先順位の実行の優先順位です。
でメインスレッド弟.join()メソッドを実行するとき、メインスレッドは、弟を与える権利の実施を考慮すべきです。
例として:
あなたがスレッドを作成した後、子スレッドが終了して取得する方法を、メインスレッドは、それを実行するには?
public class ThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName() + "i:" + i);
}
}
});
t1.start();
/* 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1 */
t1.join();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println("main" + "i:" + i);
}
}
}
印刷結果:
Thread-0i:0
Thread-0i:1
Thread-0i:2
Thread-0i:3
Thread-0i:4
Thread-0i:5
Thread-0i:6
Thread-0i:7
Thread-0i:8
Thread-0i:9
maini:0
maini:1
maini:2
maini:3
maini:4
maini:5
maini:6
maini:7
maini:8
maini:9
7、優先順位
冒頭で述べた最優先課題は、メソッドへの参加が、join()メソッドを使用した後、スレッドが完全に支配的となっているが、それはおそらくあなたが望むものではありません。
最新のオペレーティングシステムの基本的な形は、スレッドの分割を実行するようにスケジュールされ、結果の数値のスレッド割り当てられたタイムスライスはまた、多くのスレッドがプロセッサリソースを使用する方法を決定するスレッドの優先順位の概念に対応しています。前記最大10 Javaスレッド、制御優先介してINT優先度、1から10までの範囲で、デフォルト値は5です。以下では(1.8に基づく)メソッドの量及び優先上のソースコードの一部です。
class PrioritytThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().toString() + "---i:" + i);
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
PrioritytThread prioritytThread = new PrioritytThread();
Thread t1 = new Thread(prioritytThread);
Thread t2 = new Thread(prioritytThread);
t1.start();
/* 注意设置了优先级, 不代表每次都一定会被执行。 只是CPU调度会有限分配 */
t1.setPriority(10);
t2.start();
}
}
印刷結果:
Thread[t1,10,main]---i:0
Thread[t1,10,main]---i:1
Thread[t1,10,main]---i:2
Thread[t1,10,main]---i:3
Thread[t1,10,main]---i:4
Thread[t1,10,main]---i:5
Thread[t1,10,main]---i:6
Thread[t1,10,main]---i:7
Thread[t1,10,main]---i:8
Thread[t1,10,main]---i:9
Thread[t2,5,main]---i:0
Thread[t2,5,main]---i:1
Thread[t2,5,main]---i:2
Thread[t2,5,main]---i:3
Thread[t2,5,main]---i:4
Thread[t2,5,main]---i:5
Thread[t2,5,main]---i:6
Thread[t2,5,main]---i:7
Thread[t2,5,main]---i:8
Thread[t2,5,main]---i:9
7、一般的な面接の質問
プロセスとスレッドの違いは?
:プロセスは、すべてのスレッドの組であり、各スレッドは、実行プロセスのパスです。
なぜマルチスレッドを使うのか?
A:このプログラムは、効率を向上させるために
作成する方法をマルチスレッド?
:継承スレッドや、Runnableインタフェース。
優れた実装継承Threadクラスや、Runnableインタフェースを使用していますか?
:クラス継承Threadクラスが他方を継承することができない場合はまあ、Runnableインタフェースを実装し、拡張性の継承が強くない、Javaの合計は、単一継承をサポートしています。
どこでマルチスレッドを使うのですか?
メインは、効率を向上させるマルチスレッドプログラムを具現化します。
例:バッチは、SMSメッセージを送信します。
8、締結
私たちは、互いに独立して、スレッドは実行パスが何であるかのスレッド、各スレッドを学びました。
、シングルスレッドマルチスレッド、マルチスレッド化されたものを並列に異なる実行パスの数、効率を向上させるために、プログラムの目的を理解します。
継承Threadクラスは、runメソッドを実装し、または、Runnableインタフェースを実装しています。二つの方法で、共通のスレッドを作成することを学びます。
実際には、これらの2つの方法の実際の開発は一般的ではありませんが、スレッドプールの使用が管理するように。
いくつかの州、新しい、準備、実行している、ブロッキング、死のスレッドをご覧ください。
また、優先されるスレッドを学び、レコードへの1のスケールで、デフォルトでは最大値はsetPriorityを(10)を呼び出すことによって設定され、10で、5である優先順位、大きくない優先順位のことを言及する必要性あなたは最初に実行しなければならないが、優先順位を実行する確率は大きくなければなりません。
私は学習の独自の方法を記録するためにJava関連の公共番号を作成し、興味のあるパートナーは、小さなマイクロチャネルパブリック数カザフスタンを見ることができます。niceyoo