假设你现在变成京东老总,你会遇到一个问题:在仓库容量有限的情况下,控制货物存放,同时将货物送出。如何控制这种情况呢?在java中,我们可以借用生产消费模型来完成。
问题可以简化为:生产者生产货物放在仓库里,而消费者从仓库拿出货物
但是我们也会遇到一些问题:效率过低,仓库满空情况的判断
解决思路:利用并发式提高效率,借助线程状态来配合仓库满空情况。
现在正式开始:
1.建立仓库类,成员数据为货物数量。
2.建立生产者线程:
值得去搜索一下线程各个状态!
/**
* 线程等待wait,即线程没有操作权,无论cpu有无分配到时间都不会执行
* 线程唤醒notify,即将线程唤醒,获取操作权,只要得到cpu时间就可运行
* 使用wait,notify之前要获取对象监视器,不然会抛出IllegalMonitorStateException异常
* wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。
* 但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
* 之所以用lock也可以释放锁,因为ReentrantLock是基于synchronized而所写的
*/
public class Producer implements Runnable{
//得到唯一仓库对象,方便上锁以及wait方法
private Store store;
public Producer(Store store){
this.store = store;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 由于并发式操作,为了保证线程安全,需要使用“锁”
* 但是,必须保证锁和wait作用于同一对象,不然会出现“死锁”现象
*/
synchronized (store) {
/**
* 线程等待wait,即线程没有操作权,无论cpu有无分配到时间都不会执行
* 线程唤醒notify,即将线程唤醒,获取操作权,只要得到cpu时间就可运行
* 使用wait,notify之前要获取对象监视器,不然会抛出IllegalMonitorStateException异常
* wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。
* 但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
* 之所以用lock也可以释放锁,因为ReentrantLock是基于synchronized而所写的
*/
if (store.N >= 20){
try {
//得知仓库已满状态
System.out.println("仓库已满"+Thread.currentThread().getName()+"生产者进入等待状态");
store.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//如果没有满,则开始生产
store.N++;
System.out.println(Thread.currentThread().getName() + "线程 正在生产数据... " + store.N);
/**
* 开始唤醒生产者,进行生产,给消费者提供数据消费
* 同时保证了,生产消费可以一直进行下去。
*/
store.notify();
}
}
}
}
}
3.建立消费者线程:
思路与生产者线程一致。
4.在仓库内启动线程:
public void start(){
Producer producer= new Producer(this);
new Thread(producer).start();
new Thread(producer).start();
new Thread(producer).start();
Consumer consumer = new Consumer(this);
new Thread(consumer).start();
new Thread(consumer).start();
}
public static void main(String[] args) {
Store ss = new Store();
ss.start();
}
运行结果: