Java多线程实现生产者消费者模式
Java多线程实现生产者消费者模式
在我学到java多线程的时候,老师让写一个生产者消费者模式,实现生产消费同步进行,但是仓库库存低于30%时消费者无法购买产品,库存满时生产者无法生产。
关键代码
下面展示一些 关键代码仅供参考。
1.生产者类
package com.jql.homework3;
/**
* 生产者
*/
public class Productor extends Thread{
//仓库
private WareHouse wareHouse;
/**
* 构造函数
* @param productorName
* @param wareHouse
*/
public Productor(String productorName, WareHouse wareHouse) {
super(productorName);
this.wareHouse = wareHouse;
}
@Override
public void run() {
//循环生产
while (true){
//同步仓库
synchronized(wareHouse){
//判断仓库是否生产满
if (wareHouse.getCapacity() < wareHouse.getMaxCapacity()){
//未满则生产产品并将产品加入仓库
Object ware = new Object();
wareHouse.addWare(ware);
System.out.println("生产者" + this.getName() + "生产了产品" + ware.hashCode());
System.out.println("当前商品库存为:" + wareHouse.getCapacity() + "\n");
//当前库存超过30%则通知消费者可以购买
if (wareHouse.getCapacity()/wareHouse.getMaxCapacity() >= 0.3){
wareHouse.notifyAll();
}
}
//满了则停止生产等待商品销售
else {
System.out.println("库存已满,生产者" + this.getName() + "停止生产!\n");
try {
wareHouse.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.消费者类
package com.jql.homework3;
/**
* 消费者
*/
public class Customer extends Thread{
//仓库
private WareHouse wareHouse;
//排队队列
private CustomersLine customersLine;
/**
* 构造函数
* @param name
* @param wareHouse
* @param customersLine
*/
public Customer(String name, WareHouse wareHouse, CustomersLine customersLine) {
super(name);
this.wareHouse = wareHouse;
this.customersLine = customersLine;
}
@Override
public void run() {
//循环购买
while(true){
//同步仓库
synchronized(wareHouse) {
//判断当前消费者是否在队列中
if (customersLine.isInLine(this.getName())) {
//如果在判断当前库存是否足够
if ((double) wareHouse.getCapacity() / wareHouse.getMaxCapacity() >= 0.3) {
//如果足够则判断该消费者是否排在第一个
if (customersLine.getFirstCustomer().equals(this.getName())) {
//如果是第一个则允许购买
Object ware = wareHouse.sellWare();
System.out.println("消费者" + this.getName() + "购买了产品" + ware.hashCode());
System.out.println("当前商品库存为:" + wareHouse.getCapacity());
//将该消费者移除队列
customersLine.quitLine(this.getName());
//打印当前队列
customersLine.showCustomerList();
}
//如果不是第一个则继续排队
else {
System.out.println("未排到消费者" + this.getName() + ",需继续排队!");
//打印当前队列
customersLine.showCustomerList();
// try {
// wareHouse.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
//如果当前库存不足则
else {
System.out.println("当前库存已不足30%,无法进行销售!\n");
//通知生产者生产
wareHouse.notifyAll();
try {
//消费者排队等待
wareHouse.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//如果当前消费者不在队列中则加入队列
else {
customersLine.joinLine(this.getName());
System.out.println("消费者" + this.getName() + "加入排队");
//打印当前队列
customersLine.showCustomerList();
}
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.仓库类
package com.jql.homework3;
import java.util.LinkedList;
/**
* 仓库
*/
public class WareHouse {
//存储货物的链表
private LinkedList wareList;
//仓库容量
private int maxCapacity;
/**
* 构造函数
* @param maxCapacity
*/
public WareHouse(int maxCapacity) {
this.maxCapacity = maxCapacity;
this.wareList = new LinkedList();
}
/**
* 添加商品
* @param object
* @return
*/
public boolean addWare(Object object){
//判断是否超过库存
if (wareList.size() < maxCapacity){
wareList.add(object);
return true;
}
return false;
}
/**
* 卖出商品
* @return
*/
public Object sellWare(){
return wareList.removeFirst();
}
/**
* 获得当前商品库存
* @return
*/
public int getCapacity(){
return wareList.size();
}
/**
* 获得仓库容量
* @return
*/
public int getMaxCapacity() {
return maxCapacity;
}
}
总结和问题
1.使用java通过多线程和同步实现生产者消费者模式时要注意何时加锁,何时释放锁;
2.该程序在实际问题中的考虑还不够深入,但基本实现了的题目要求。