// 启动类
public class Bootstap {
private final String configFile = “init.properties”;
private Properties properties = new Properties();
private Bakery bakery = new Bakery();
private List bakerContainer = new LinkedList<>();
private GuestContainer guestContainer = new GuestContainer(bakery);
{
String basePath = ClassLoader.getSystemClassLoader().getResource("").getPath();
File file = new File(basePath, configFile);
if (file.exists() && file.isFile()) {
try {
properties.load(new FileInputStream(file));
} catch (IOException e) {
// undo
}
}
}
public void init() {
// 设置面包房最大储存量
bakery.setCapacity(getInt("bakerycapacity"));
// 初始面包类型
String[] types = getString("breadtype").split(" ");
for (int i = 0; i < types.length; i++) {
bakery.addBreadType(new Bread(i, types[i]));
}
// 初始化面包师能力
int bakernums = getInt("bakerycapacity");
int maxmakebreadspeed = getInt("maxmakebreadspeed");
for (int i = 0; i < bakernums; i++) {
Baker baker = new Baker(bakery);
baker.setSpeed(RandomUtils.getRandom(maxmakebreadspeed));
bakerContainer.add(baker);
}
// 初始化顾客容器
guestContainer.setMaxWaitTime(getInt("maxwaittime"));
guestContainer.setMinWaitTime(getInt("minwaittime"));
guestContainer.setMaxGenerateTime(getInt("maxgeneratetime"));
guestContainer.setMinGenerateTime(getInt("mingeneratetime"));
}
public void start() {
for (Baker baker : bakerContainer) {
new Thread(baker).start();
}
guestContainer.start();
}
private String getString(String key) {
String value = this.properties.getProperty(key, "");
try {
return new String(value.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
// undo
}
return "";
}
private int getInt(String key) {
String value = this.properties.getProperty(key, "0");
return Integer.valueOf(value);
}
public static void main(String[] args) {
Bootstap bootstap = new Bootstap();
bootstap.init();
bootstap.start();
}
}
// 面包仓
public class Bakery {
private int capacity;
private List breadTypes = new ArrayList<>();
private Map<Integer, List> store = new HashMap();
private Map<Integer, ReentrantLock> storeLock = new HashMap<>();
private Map<Integer, Condition> fullCondition = new HashMap<>();
private Map<Integer, Condition> emptyCondition = new HashMap<>();
public void addBreadType(Bread bread) {
breadTypes.add(bread);
int id = bread.getType();
store.put(id, new LinkedList<Bread>());
ReentrantLock reentrantLock = new ReentrantLock();
storeLock.put(id, reentrantLock);
fullCondition.put(id, reentrantLock.newCondition());
emptyCondition.put(id, reentrantLock.newCondition());
}
public void makeBread() {
int breadTypeNums = breadTypes.size();
int typeIndex = RandomUtils.getRandom(breadTypeNums - 1);
ReentrantLock currentBreadLock = storeLock.get(typeIndex);
try {
currentBreadLock.lock();
List<Bread> currentBreadList = store.get(typeIndex);
if (currentBreadList.size() >= this.capacity) {
// 满了
Condition currentFullCondition = fullCondition.get(typeIndex);
currentFullCondition.await();
}
Bread madeBread = (Bread) breadTypes.get(typeIndex).clone();
currentBreadList.add(madeBread);
System.out.println("生产了一个" + madeBread.getName() + "面包");
Condition emptyFullCondition = emptyCondition.get(typeIndex);
emptyFullCondition.signalAll();
} catch (InterruptedException e) {
// undo
} finally {
currentBreadLock.unlock();
}
}
public void sellBread() {
int breadTypeNums = breadTypes.size();
int sellTypeNums = RandomUtils.getRandom(breadTypeNums);
HashSet<Integer> exitedIndex = new HashSet<>();
for(int i = 0; i < sellTypeNums; i++) {
if (exitedIndex.contains(i)) {
continue;
}
int wantToBuyNum = RandomUtils.getRandom(this.capacity);
ReentrantLock currentBreadLock = storeLock.get(i);
try {
currentBreadLock.lock();
List<Bread> currentBreadList = store.get(i);
for (int j = 0; j < wantToBuyNum; j++) {
if (currentBreadList.size() <= 0) {
Condition emptyFullCondition = emptyCondition.get(i);
emptyFullCondition.await();
}
currentBreadList.remove(0);
Condition currentFullCondition = fullCondition.get(i);
currentFullCondition.signalAll();
}
Bread currentBread = breadTypes.get(i);
System.out.println("买走了" + wantToBuyNum + "个" + currentBread.getName() + "面包");
} catch (InterruptedException e) {
// undo
} finally {
currentBreadLock.unlock();
}
}
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
}
// 面包
public class Bread implements Cloneable{
private int type;
private String name;
public Bread(int type, String name) {
this.type = type;
this.name = name;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Object clone() {
Bread bread = null;
try {
bread = (Bread)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return bread;
}
}
// 面包师
public class Baker implements Runnable{
private Bakery bakery;
private int speed;
public Baker(Bakery bakery) {
this.bakery = bakery;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
@Override
public void run() {
while (true) {
bakery.makeBread();
try {
Thread.sleep(this.speed * 1000);
} catch (InterruptedException e) {
// undo
}
}
}
}
// 顾客
public class Guest implements Runnable{
private Bakery bakery;
private int id;
private long creatTime;
private long waitTime;
public Guest(Bakery bakery) {
this.bakery = bakery;
this.creatTime = System.currentTimeMillis();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public long getCreatTime() {
return creatTime;
}
public void setCreatTime(long creatTime) {
this.creatTime = creatTime;
}
public long getWaitTime() {
return waitTime;
}
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
@Override
public void run() {
bakery.sellBread();
}
}
// 顾客容器
public class GuestContainer {
private int idContainer = 0;
private List guestList = new LinkedList<>();
private GenerateHandler generateHandler = new GenerateHandler();
private TimeoutHandler timeoutHandler = new TimeoutHandler();
private CustomHandle customHandle = new CustomHandle();
private Bakery bakery;
private int maxWaitTime;
private int minWaitTime;
private int minGenerateTime;
private int maxGenerateTime;
public GuestContainer(Bakery bakery) {
this.bakery = bakery;
}
public int getMaxWaitTime() {
return maxWaitTime;
}
public void setMaxWaitTime(int maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}
public int getMinWaitTime() {
return minWaitTime;
}
public void setMinWaitTime(int minWaitTime) {
this.minWaitTime = minWaitTime;
}
public int getMinGenerateTime() {
return minGenerateTime;
}
public void setMinGenerateTime(int minGenerateTime) {
this.minGenerateTime = minGenerateTime;
}
public int getMaxGenerateTime() {
return maxGenerateTime;
}
public void setMaxGenerateTime(int maxGenerateTime) {
this.maxGenerateTime = maxGenerateTime;
}
public void start() {
new Thread(this.generateHandler).start();
new Thread(this.timeoutHandler).start();
new Thread(this.customHandle).start();
}
private class GenerateHandler implements Runnable {
@Override
public void run() {
while (true) {
synchronized (guestList) {
int randomTime = RandomUtils.getRandom(maxGenerateTime);
if (randomTime < minGenerateTime) {
randomTime = minGenerateTime;
}
try {
Thread.sleep(randomTime * 1000);
} catch (InterruptedException e) {
// undo
}
Guest guest = new Guest(bakery);
int waitTime = RandomUtils.getRandom(maxWaitTime);
if (waitTime < minWaitTime) {
waitTime = minWaitTime;
}
guest.setWaitTime(waitTime);
guest.setId(idContainer++);
guestList.add(guest);
System.out.println("顾客" + guest.getId() + "进店");
}
}
}
}
private class TimeoutHandler implements Runnable {
@Override
public void run() {
while (true) {
synchronized (guestList) {
Iterator<Guest> iterator = guestList.iterator();
while (iterator.hasNext()) {
Guest currentGuest = iterator.next();
long currentTime = System.currentTimeMillis();
if ((currentTime - currentGuest.getCreatTime()) > currentGuest.getWaitTime() * 1000) {
iterator.remove();
System.out.println("顾客" + currentGuest.getId() + "不想等待而离开店了");
}
}
}
}
}
}
private class CustomHandle implements Runnable {
@Override
public void run() {
while (true) {
synchronized (guestList) {
if (guestList.size() > 0) {
Guest guest = guestList.remove(0);
guest.run();
System.out.println("顾客" + guest.getId() + "买完东西离开店了");
}
}
}
}
}
}
// 工具类
public class RandomUtils {
private static final SecureRandom randon = new SecureRandom();
public static int getRandom(int round) {
return randon.nextInt(round);
}
}