生産者/消費者モデルの概要
待機とウェイクアップを本番と消費のプロセスに反映するために、Javaには、使用できるいくつかのメソッドが用意されています。これらのメソッドは、ObjectクラスのObjectクラスの待機メソッドとウェイクアップメソッドです。
-
void wait():別のスレッドがオブジェクトのnotify()メソッドまたはnotifyAll()メソッドを呼び出すまで、現在のスレッドを待機させます
-
void notify():オブジェクトモニターを待機している単一のスレッドをウェイクアップします
-
void notifyAll():オブジェクトモニターを待機しているすべてのスレッドをウェイクアップします
場合:
生産者はミルクを生産してミルクボックスに送り、消費者はミルクボックスからミルクを取り出すことができますが、生産者は消費者がミルクを受け取るのを待ってから入れ、消費者はミルクを入れる生産者。それを取り除いて、プログラムでそれを実行してください。
アイデア:
生産者/消費者事件に含まれるクラス:
- ミルクボックスクラス(ボックス):ミルクのx番目のボトルを表すメンバー変数を定義し、ミルクを保存してミルクを取得するための操作を提供します
- プロデューサークラス(プロデューサー):Runnableインターフェイスを実装し、run()メソッドを書き直して、ミルクを保存する操作を呼び出します。
- コンシューマークラス(Customer):Runnableインターフェイスを実装し、run()メソッドを書き直して、ミルクを取得する操作を呼び出します。
- テストクラス(BoxDemo):メインメソッドがあります。メインメソッドのコードステップは次のとおりです。①
共有データ領域であるミルクボックスオブジェクトを作成します
。②プロデューサーオブジェクトを作成し、ミルクボックスオブジェクトをとして渡します。コンストラクターパラメータ、このクラスではミルクを格納する操作を呼び出す
③コンシューマーオブジェクトを作成するには、ミルクボックスオブジェクトをコンストラクターパラメーターとして渡します。このクラスでは、ミルクを取得する操作を呼び出す必要があるためです
。④2つのスレッドオブジェクトを作成します。構築メソッドパラメータ転送としてのプロデューサオブジェクトとコンシューマオブジェクト
⑤開始スレッド
まず、Boxクラスを作成します。
Boxクラスでは、wait()およびnotifyAll()操作を使用して、消費を待機し、本番を待機するプロセスを実現します。特にコードを見てください。
package 生产者消费者;
public class Box {
//定义一个成员变量,表示第x瓶奶
private int milk;
//定义一个成员变量,表示奶箱状态
private boolean state=false;
//提供存储牛奶和获取牛奶的操作
public synchronized void put(int milk) {
//如果有牛奶,等待消费
if(state) {
try {
wait();
} catch ( InterruptedException e) {
e.printStackTrace();
}
}
//如果没有,就生产牛奶
this.milk=milk;
System.out.println("送奶工将第"+this.milk+"瓶奶放入奶箱");
state=true;
//唤醒其他等待的线程
notifyAll();
}
public synchronized void get() {
//如果没有牛奶,就等待生产
if(!state) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有牛奶,就消费
System.out.println("用户拿到第"+this.milk+"瓶奶");
state=false;
//唤醒其他等待的线程
notifyAll();
}
}
プロデューサークラス:
package 生产者消费者;
public class Productor implements Runnable{
private Box b;
public Productor(Box b) {
this.b=b;
}
@Override
public void run() {
for(int i=1;i<=5;i++) {
b.put(i);
}
}
}
消費者カテゴリー:
package 生产者消费者;
public class Customer implements Runnable{
private Box b;
public Customer(Box b) {
this.b=b;
}
@Override
public void run() {
while(true) {
b.get();
}
}
}
メインクラス:
package 生产者消费者;
public class BoxDemo {
public static void main(String[] args) {
//创建奶箱对象,这是共享数据区域
Box b=new Box();
//创建生产者对象,把奶箱对象作为构造方法参数传递, 因为在这个类中要调用存储牛奶的操作
Productor p=new Productor(b);
//创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作
Customer c=new Customer(b);
//创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
Thread t1=new Thread(p);
Thread t2=new Thread(c);
//启动线程
t1.start();
t2.start();
}
}