生産消費者モデル
マルチスレッドの典型的な応用は生産消費者モデルであり、このモデルは実際にはマルチスレッドの通信であり、notify/waitメカニズムを使用している.このモデルの利点は、生産者がバッファにデータを書き、消費者がバッファデータを使用することで、論理が明確になり、また、速く遅くなることを避けることができるバッファがあることです.このモードは1/1,1/N,N/N,N/1のモードに分かれている.その原理はすべて同じで、ここで1/1の例を書きます.
ここでcacheオブジェクトはバッファとして、lockはロックオブジェクトとして機能します.生産消費者はバッファにデータを読み書きし続けている.以下のコードをよく分析すると、1/1の生産消費が比較的簡明であることがわかります.
生産者スレッドを参照:
消費者スレッドを見てみましょう.
最後の実行クラス:
最後の実行結果は次のとおりです.
the value for producer is: 5202433063937 The value for consumer is: 5202433063937 the value for producer is: 5208443181133 The value for consumer is: 5208443181133 consumer begin to wait. the value for producer is: 5214461465895 consumer end to wait. The value for consumer is: 5214461465895 the value for producer is: 5220470907482 producer begin to wait. The value for consumer is: 5220470907482
ここでcacheオブジェクトはバッファとして、lockはロックオブジェクトとして機能します.生産消費者はバッファにデータを読み書きし続けている.以下のコードをよく分析すると、1/1の生産消費が比較的簡明であることがわかります.
生産者スレッドを参照:
package com.lenovo.plm.dms.p12;
import java.util.Map;
public class MyThreadA extends Thread{
Map<String,String> cache;
Object lock;
public MyThreadA(Map<String,String> cache,Object lock){
this.cache = cache;
this.lock = lock;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true){
synchronized(lock){
if(cache.size() != 0){
System.out.println(Thread.currentThread().getName() + " begin to wait.");
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end to wait.");
}
long time = System.nanoTime();
System.out.println("the value for producer is: " + time);
cache.put("time",String.valueOf(time));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.notify();
}
}
}
}
消費者スレッドを見てみましょう.
package com.lenovo.plm.dms.p12;
import java.util.Map;
public class MyThreadB extends Thread{
Map<String,String> cache;
Object lock;
public MyThreadB(Map<String,String> cache,Object lock){
this.cache = cache;
this.lock = lock;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true){
synchronized(lock){
if(cache.size() == 0){
System.out.println(Thread.currentThread().getName() + " begin to wait.");
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end to wait.");
}
System.out.println("The value for consumer is: " + cache.get("time"));
cache.remove("time");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.notify();
}
}
}
}
最後の実行クラス:
package com.lenovo.plm.dms.p12;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Object lock = new Object();
Map<String,String> cache = new HashMap<String,String>();
MyThreadA t1 = new MyThreadA(cache,lock);
t1.setName("producer");
t1.start();
MyThreadB t2 = new MyThreadB(cache,lock);
t2.setName("consumer");
t2.start();
}
}
最後の実行結果は次のとおりです.
the value for producer is: 5202433063937 The value for consumer is: 5202433063937 the value for producer is: 5208443181133 The value for consumer is: 5208443181133 consumer begin to wait. the value for producer is: 5214461465895 consumer end to wait. The value for consumer is: 5214461465895 the value for producer is: 5220470907482 producer begin to wait. The value for consumer is: 5220470907482