基本概念
はじめに
久しぶりに記事を書く。最近、Javaのスレッドに関する知識をまとめている。それがこの記事だ。インターネット上にはJavaスレッドに関する記事がたくさんある。
もちろん、RXJavaフレームワークを使っている友人はたくさんいる。個人的な仕事の都合で、RxJavaフレームワークにはあまり理解がない。スレッド "関連の知識には接している。
たくさん使っていると、いつもまとめて整理したくなる。それゆえこの記事を書いた。
スレッドの知識構造
マルチスレッドに関する知識をまとめ、構造図をまとめる。
スレッドの基本
スレッドとは:
スレッドは、オペレーティング・システムによってスケジューリングされる計算の最小単位である。プロセス内に含まれ、プロセス内での実際の演算単位である。
スレッドとプロセスの違い
1. スレッドはCPUスケジューリングの最小単位である。
2. プロセスとは、リソースを割り当てるオペレーティング・システムの最小単位である。
同期とは:
同期とは、プログラムが異なるスレッド間で発生する操作の相対的な順序を制御するメカニズムである。
並行処理と並列処理の違い:
1. 同時実行:複数のスレッドが同じCPU上で交互に実行される。複数のスレッドが同時に実行されているような効果を得るために、CPUによって異なるCPUタイム・スライスが割り当てられる。
2. 並列処理:複数のCPU上で複数のスレッドが同時に実行される。
コンテキストの切り替えとは:
シングルコアのCPU上で同時に実行されているスレッドAとスレッドBがあるとする。Aを実行しているCPUには対応するCPUのタイムスライスが割り当てられ、その中でAで実行されている内容の関連スレッドの命令とデータをメモリからロードする。タイムスライスが終了すると、現在のスレッド実行のデータと命令アドレスがメモリにセーブバックされる。次に、スレッドBに関連する命令とデータがメモリからロードされる。
.タスクの保存からロードまでのこのプロセスは、スレッド・コンテキスト・スイッチと呼ばれる。
Wait/Notify 待機/通知
1. スレッドを待機状態にする。notifyまたはnotifyAllメソッドを実行して起こす。
//オブジェクトをロックする
private Object obj=new Object();
//判定条件
private volatile boolean isNotify=false;
//スレッドAで待つ
//1.
//2.while判定条件
//3. .wait()
public void wait() {
synchronized (obj) {
while (!isNotify) {
obj.wait();//waitロックが解除されるのは
}
}
}
//スレッドBでウェイクアップする
//1.
//2.判定条件を変更する
//3. .notify() / .notifyAll()
//4.notifyスレッドAはすぐにwaitから復帰せず、スレッドAがwaitから復帰する前にロックが解放されるのを待たなければならない
public void notify(){
synchronized(obj){
isNotify=true;
obj.notify();//obj.notifyAll();
}
}
デッドロックとは:
- 両スレッドは同時にもう一方のスレッドがロックを解放するのを待ちます。
private Object A = new Object();
private Object B = new Object();
/**
* 1. スレッドセアド_Aスレッド ThreadのロックAを取得する。_BロックBの取得
* 2. スレッド Thread_AThreadを待つ_BロックBを解放する
* 3. スレッド Thread_BThreadを待つ_AロックAを解放する
* 4. 2つのスレッドがお互いを待ち、デッドロックを発生させる
*/
protected void deadLock () {
Thread thead_A = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
//他の操作を行う
}
}
}
});
Thread thead_B = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (A) {
//他の操作を行う
}
}
}
});
thead_A.start();
thead_B.start();
}
デッドロックを回避する方法:
1. 同じロックは同じスレッドでしか使わない。
2. JUCを使う.util.concurrent ReentrantLock、CountDownLauchなど)パッケージのロックは、タイムアウトを設定する。キーワードsynchronizedの代わりに使用する。
基本的なことは以上だ。何か問題があればこの記事は将来更新されるだろう。この記事が皆さんのお役に立てれば幸いである。できれば、ブックマークを忘れずに、、、コイン..... スレッドをつなげているようだ。とにかく、次のことを覚えておいてほしい。 ~