生产者消费者模型
生产者消费者模式是什么?
- 生产者只在仓库未满时进行生产,仓库满时生产者进程被阻塞;
- 消费者只在仓库非空时进行消费,仓库为空时消费者进程被阻塞;
- 当消费者发现仓库为空时会通知生产者生产;
- 当生产者发现仓库满时会通知消费者消费;
敲了一天,头给我敲大了。待会儿再试试。
__________________________________________________________________________________________________
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
这并不是最好的思路,还有许多待改进的地方,比如本例子释放锁之后消费者和生产者都被唤醒这样是不好的,应该消费者发现货架空了之后只会唤起生产者,生产者发现货架满了只会唤起消费者。还有本例中只能有一个人去买或去卖商品,这样效率并不高,应当改进成能多个人卖,多个人买。