コミュニケーションの手段
ように実行のスレッドの結果を得るために、スレッドの実行順序、および次のような複数のスレッド間の相乗効果を達成するために。次の4つのカテゴリに分割されるスレッド間の相互通信に関する。
-
ファイル共有
-
ネットワーク共有
-
共有変数
-
JDKは、コーディネーションAPIのスレッドを提供します
待機/通知、サスペンド/レジューム、公園/ unparkを:に細分
ファイル共有
プロセス:スレッド-1書き込みデータファイルシステムには、スレッド、そこからデータを読み出す-2。
public class Demo5 {
public static void main(String[] args) {
//线程1 写入数据
new Thread(() -> {
try {
while (true) {
Files.write(Paths.get("Demo6.log"),("当前时间为" + String.valueOf(System.currentTimeMillis())).getBytes());
Thread.sleep(1000L);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
//线程2 读取数据
new Thread(()->{
try {
while (true){
Thread.sleep(1000L);
byte[] allBytes = Files.readAllBytes(Paths.get("Demo6.log"));
System.out.println(new String(allBytes));
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
共有変数
工程:次に、メモリへのスレッド-1書き込みデータとスレッド-2可変コンテンツは、データを読み出します。
public class Demo5 {
public static String context = "";
public volatile static Boolean flag = true;
public static void main(String[] args) throws InterruptedException {
//线程1 写入数据
Thread thread1 = new Thread(() -> {
try {
while (flag) {
context = "当前时间为:" + System.currentTimeMillis();
Thread.sleep(1000L);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
Thread.sleep(5000L);
flag = false;
//线程2 读取数据
new Thread(()->{
try {
while (true){
Thread.sleep(1000L);
System.out.println(context);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
スレッドのコラボレーション - JDK API
タスクを達成するために協力を必要としているJDKは、APIのサポートを提供し、シナリオをマルチスレッド。
消費者モデル - プロデューサー:典型的なシナリオは、マルチスレッドのコラボレーションです。(スレッドがブロックされ、スレッドの航跡)
API - 非推奨の一時停止と再開
役割:ターゲット・スレッドを一時停止、サスペンド呼び出し、スレッドは、再開することによって実行を再開することができます。
public class Demo6 {
static Object baozhi = null;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
while (baozhi == null){
System.out.println("没有包子,进入等待");
Thread.currentThread().suspend();
System.out.println("买到包子,回家");
}
});
Thread thread2 = new Thread(()->{
while (baozhi == null){
System.out.println("生产包子");
baozhi = new Object();
System.out.println("通知顾客来买包子");
thread1.resume();
}
});
thread1.start();
Thread.sleep(1000L);
thread2.start();
}
}
結果:
何のパンはありませんが、待機入力
パンが生産を
パンを購入する顧客に通知
パンを購入し、家
**主な理由は、簡単に書き込み、コードのデッドロックを断念しました。**シーケンスを呼び出し、および一時停止すると、ロックを解除しないことに注意してください。
待機/メカニズムを通知
これらのメソッドは、それ以外の場合は、例外は、IllegalMonitorStateExceptionがスローされます、同期ブロックの内部に書かれている同じオブジェクトのロックホルダのスレッドで呼び出すことができます。
待機メソッドは、スレッドの集まりに参加するのを待って、現在のスレッドを待機させて、開催された現在のオブジェクトのロックを放棄します。
通知/のnotifyAll方法は、1つまたはオブジェクトのロック・スレッドのすべてを覚ますのを待っています。
注:待ち時間が後に自動的に呼び出された通知場合は、waitメソッドを呼び出すために始めたが、順序の要件によってロックを解除しますが、スレッドは常に待ち状態になります。
public class Demo6 {
static Object baozhi = null;
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
while (baozhi == null){
synchronized (lock){
System.out.println("没有包子,进入等待");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("买到包子,回家");
}
}
});
Thread thread2 = new Thread(()->{
while (baozhi == null){
synchronized (lock){
System.out.println("生产包子");
baozhi = new Object();
System.out.println("通知顾客来买包子");
lock.notify();
}
}
});
thread1.start();
Thread.sleep(1000L);
thread2.start();
}
}
公園/ unparkをメカニズム
スレッドは、公園には「許可」を待っている呼び出し、unparkをメソッドは、指定されたスレッドは、「許可」を提供します。
これは、シーケンス公園とアンパックメソッドを呼び出す必要はありません。
unparkをへの複数の呼び出した後で、公園を呼び出し、スレッドが直接実行されます。
しかし、スタックしていない、つまり、初めての連続方法を駐車する複数の呼び出しは、直接実行するには、「許可」を取得します、後続の呼び出しは、待ち時間を入力します。
public class Demo6 {
static Object baozhi = null;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (baozhi == null) {
System.out.println("没有包子,进入等待");
LockSupport.park();
System.out.println("买到包子,回家");
}
});
Thread thread2 = new Thread(() -> {
while (baozhi == null) {
System.out.println("生产包子");
baozhi = new Object();
System.out.println("通知顾客来买包子");
LockSupport.unpark(thread1);
}
});
thread1.start();
Thread.sleep(1000L);
thread2.start();
}
注:公園が/順序に注意を呼び出す必要はありませんパーキング位置から外しますが、公園はロックを解除しようとしていないときに。
擬似ウェイク
待機状態に入るかどうかを決定するためにif文を使用してコードでは、間違っています!!
公式の推奨事項は、ループ内で待機状態を確認する必要がありますスレッドが受け取ることが待機状態であるため、誤報やスプリアスウェイク条件を待っているループチェックでない場合は、終了条件が満たされずに、プログラムが終了します。
擬似ウェイクがスレッドを参照するため、のnotifyAll、通知などのウェイクアップコールAPIとしてunparkを、より根本的な原因ではありません。
公園は、一時停止、待機メソッドは、ネイティブメソッドです。