JAVA ------生産者/消費者

生産者/消費者モデルの概要

待機とウェイクアップを本番と消費のプロセスに反映するために、Javaには、使用できるいくつかのメソッドが用意されています。これらのメソッドは、ObjectクラスのObjectクラスの待機メソッドとウェイクアップメソッドです。

  • void wait():別のスレッドがオブジェクトのnotify()メソッドまたはnotifyAll()メソッドを呼び出すまで、現在のスレッドを待機させます

  • void notify():オブジェクトモニターを待機している単一のスレッドをウェイクアップします

  • void notifyAll():オブジェクトモニターを待機しているすべてのスレッドをウェイクアップします


場合:

生産者はミルクを生産してミルクボックスに送り、消費者はミルクボックスからミルクを取り出すことができますが、生産者は消費者がミルクを受け取るのを待ってから入れ、消費者はミルクを入れる生産者。それを取り除いて、プログラムでそれを実行してください。

アイデア:

生産者/消費者事件に含まれるクラス:

  1. ミルクボックスクラス(ボックス):ミルクのx番目のボトルを表すメンバー変数を定義し、ミルクを保存してミルクを取得するための操作を提供します
  2. プロデューサークラス(プロデューサー):Runnableインターフェイスを実装し、run()メソッドを書き直して、ミルクを保存する操作を呼び出します。
  3. コンシューマークラス(Customer):Runnableインターフェイスを実装し、run()メソッドを書き直して、ミルクを取得する操作を呼び出します。
  4. テストクラス(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();
	}

}

おすすめ

転載: blog.csdn.net/weixin_45102820/article/details/113762240