生产者消费者模型

 

生产者消费者模式是什么?

  1. 生产者只在仓库未满时进行生产,仓库满时生产者进程被阻塞;
  2. 消费者只在仓库非空时进行消费,仓库为空时消费者进程被阻塞;
  3. 当消费者发现仓库为空时会通知生产者生产;
  4. 当生产者发现仓库满时会通知消费者消费;

敲了一天,头给我敲大了。待会儿再试试。

__________________________________________________________________________________________________

2018.10.14总算自己捣鼓了一个能跑出结果的DEMO。具体思路是这样的,四个类:卖家类、买家类、商城类、Main函数类。

买家、卖家负责调用商城类的静态买方法和卖方法,Main函数就负责声明线程开始表演。

买家和卖家的源码比较简单,一直调用就完事儿了,然后顺路把自己的名字传过去待会儿好看结果。

package threads;
/*买家类*/
public class Buyer extends Thread {
    String name;
    public Buyer(String name) {
          this.name=name;
    }

    @Override
    public void run() {
        while (true){
            try {
                Market.buy(name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package threads;
/*卖家类*/
public  class Seller extends Thread {
    public String name ;
    public Seller(String name){
        this.name=name;
    }

    @Override
    public void run() {

        while(true){
            try {
                Market.sell("product",name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

接下来看最重要的商城类

        我对商城类的设计思路是:给这个List加锁,每次生产或者买走商品的时候,唤起所有线程再释放自己的锁,特殊情况则睡眠3秒。

       

package threads;

import java.util.ArrayList;

public class Market {
    private static final int MAX_LENTGH=10;
    public static ArrayList<String> mList=new ArrayList<>(MAX_LENTGH);;

    public static void sell(String product,String myName) throws InterruptedException {
        synchronized (mList) {
            if (mList.size() < MAX_LENTGH) {
                mList.add(product);//若没满则加
                System.out.println("卖家" + myName + "产一个,现在有"+mList.size()+"个");
                mList.notifyAll();
                mList.wait();
            }else{
                System.out.println( "货架满了!"+myName+"释放锁然后休息3秒!");
                mList.notifyAll();
                mList.wait();
                Thread.sleep(3000);
            }

        }
    }
    public static void buy(String myName) throws InterruptedException {
        synchronized (mList){
        if(!mList.isEmpty()) {
            mList.remove(0);//移除第一个元素
            System.out.println("买家"+myName+" 买一个,现在有"+mList.size()+"个");
            mList.notifyAll();
            mList.wait();
        }
        else{
            System.out.println("货架空了!"+myName+"将释放锁然后休息3秒!");
            mList.notifyAll();
            mList.wait();
            Thread.sleep(3000);
        }

      }
    }

}

接着看最终的Main函数类,3个卖家,3个买家。开工!

package defaultPk;

import threads.Buyer;
import threads.Seller;

public class BuyerAndSeller {


    public static void main(String[] args){
        Buyer buyer1=new Buyer("buyer1");
        Buyer buyer2=new Buyer("buyer2");
        Buyer buyer3=new Buyer("buyer3");
        Seller seller1=new Seller("seller1");
        Seller seller2=new Seller("seller2");
        Seller seller3=new Seller("seller3");
        buyer1.start();
        buyer2.start();
        buyer3.start();
        seller1.start();
        seller2.start();
        seller3.start();
    }
}

 

运行结果如下:

生产者消费者模型

运行结果略长。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。省略了一些

生产者消费者模型

总结

       如何让一个线程释放它的锁?lock.wait()   Thread.yield()

       如何让一个线程休眠? Thread.sleep( TIME )  

       加锁:Synchronized(THE_LOCK){ ... },在里面才可以用wait,notify

       这并不是最好的思路,还有许多待改进的地方,比如本例子释放锁之后消费者和生产者都被唤醒这样是不好的,应该消费者发现货架空了之后只会唤起生产者,生产者发现货架满了只会唤起消费者。还有本例中只能有一个人去买或去卖商品,这样效率并不高,应当改进成能多个人卖,多个人买。