多線程協(xié)作--生產(chǎn)者消費者問題


//管程法:生產(chǎn)者消費者問題(線程協(xié)作)
public class Exercise {
? ?public static void main(String[] args) {
? ?//建立緩沖區(qū)對象 作為容器
? ? ? ?Buffer container=new Buffer();
? ? ? ?new Producer(container).start();//啟動生產(chǎn)者線程
? ? ? ?new Consumers(container).start();//啟動消費者線程
? ?}
}
//生產(chǎn)者
class Producer extends Thread{
//通過緩存區(qū)建立容器
? ?Buffer buffer;
? ?//構(gòu)造器
? ?public Producer(Buffer buffer) {
? ? ? ?this.buffer = buffer;
? ?}
? ?//重寫run方法
? ?@Override
? ?public void run() {
? ? ? ?for (int i = 0; i < 100; i++) {
? ? ? ? ? ?System.out.println("生產(chǎn)了"+i+"個產(chǎn)品");
? ? ? ? ? ?buffer.Push(new Product(i));//棧入
? ? ? ?}
? ?}
}
//消費者
class Consumers extends Thread{
? ?//通過緩存區(qū)建立容器
? ?Buffer buffer;
? //構(gòu)造器
? ?public Consumers(Buffer buffer) {
? ? ? ?this.buffer = buffer;
? ?}
? ?@Override
? ?public void run() {
? ? ? ?for (int i = 0; i < 100; i++) {
? ? ? ? ? ?System.out.println("消費了"+buffer.Pop().id+"個產(chǎn)品");//棧出
? ? ? ?}
? ?}
}
//產(chǎn)品
class Product extends ?Thread{
? ?//產(chǎn)品編號
? ?int id;
? ?public Product(int id) {
? ? ? ?this.id = id;
? ?}
}
//緩沖區(qū) 負責建立容器
class ?Buffer{
? ?Product []products=new Product[10];//根據(jù)產(chǎn)品來建立容器
? ?int count=0;//計數(shù)器
? ?public synchronized void Push(Product product)//生產(chǎn)者入棧
? ?{
? ? ? ?//判斷容器是否滿
? ? ? ?//如果容器滿了,那么就等待消費者消費
? ? ? ?if (count==products.length)
? ? ? ?{
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?this.wait();
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//如果沒滿,就丟入產(chǎn)品,再通知生產(chǎn)者生產(chǎn)
? ? ? ?products[count]=product;
? ? ? ?count++;
? ? ? ?this.notifyAll();//喚醒多個線程
? ?}
? ?//消費者出棧
? ?public synchronized Product Pop(){
? ? ? ?//判斷是否可以消費
? ? ? ?//如果容器內(nèi)為空,則需要等待生產(chǎn)者生產(chǎn)
? ? ? ?if (count==0)
? ? ? ?{
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?this.wait();
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//如果容器內(nèi)有產(chǎn)品,那么就可以消費
? ? ? ?//把容器內(nèi)的產(chǎn)品,放入到產(chǎn)品的臨時變量里,隨拿隨取
? ? ? ?count--;
? ? ? ?Product product=products[count];
? ? ? ?//消費完之后,通知生產(chǎn)者去生產(chǎn)
? ? ? ?this.notifyAll();
? ? ? ?return product;
? ?}
}