-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathThriftStore.java
171 lines (118 loc) · 5.75 KB
/
ThriftStore.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class ThriftStore{
public static final int NUM_TICKS = 1000;
String[] sections = {"electronics", "clothes", "furniture", "toys", "sporting goods", "books"};
//Holds the delivery that was delivered by the Deliverer Thread
public String[] delivery;
//bool Value that lets assistants know if there is a delivery present in the store
public boolean isDelivered;
//Dictionary that holds storeInventory
Dictionary<String, Integer> storeInventory= new Hashtable<>();
public ThriftStore(){
this.delivery = new String[10];
this.isDelivered = false;
//Initialize storeInventroy with 5 items in each section
for(int i = 0; i<6; i++){
storeInventory.put(sections[i],5);
}
}
public void buy(AtomicInteger tick){
//Used Gaussian Distribution to get an average of 10 ticks per customer for purchases.s
Random random = new Random();
double randomValue = Math.abs(random.nextGaussian() * 5 + 10);
int randomNumber = (int) Math.round(randomValue);
int tickToPerformAction = tick.get() + randomNumber;
while (tick.get() < tickToPerformAction) {
}
int randomInt = random.nextInt(6);
//Wait if there is nothing in the given section.
if(storeInventory.get(sections[randomInt]) == 0){
System.out.printf("<%d> <%s> Customer Waiting for %s \n",tick.get(), Thread.currentThread().getId(),sections[randomInt]);
}
while(storeInventory.get(sections[randomInt]) == 0){}
//Only want one thread at a time to access storeInventory at a given time since this is critical data
synchronized(storeInventory){
int currentValue = storeInventory.get(sections[randomInt]);
// Decrement the value by one
int newValue = currentValue - 1;
// Put the new value back into the dictionary
storeInventory.put(sections[randomInt], newValue);
System.out.printf("<%d> <%s> Customer Bought %s \n",tick.get(), Thread.currentThread().getId(),sections[randomInt]);
}
}
public void stock(Dictionary<String,Integer> inventory, AtomicInteger tick){
//Run until out of items in Inventory
while(!inventory.isEmpty() && !allValuesAreZero(inventory)){
//Determine how long it will take to get to section with given number of items in inventory
int tickToPerformAction = tick.get() + 10 + (countNumsInInventory(inventory));
//Determine section to stock
String sectionToStock = "";
Enumeration<String> keys = inventory.keys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
int value = inventory.get(key);
if (value > 0){
sectionToStock = key;
break;
}
}
System.out.printf("<%d> <%s> Assistant Began Stocking Section %s = %d\n",tick.get(), Thread.currentThread().getId(),sectionToStock,storeInventory.get(sectionToStock));
while(tick.get() < tickToPerformAction){
}
//Use synchronize keyword to only allow one thread to access storeInventory data at a given time.
synchronized(storeInventory){
int currentValue = storeInventory.get(sectionToStock);
// Increment the value by how many in inventory
int newValue = currentValue + inventory.get(sectionToStock);
// Put the new value back into the store Inventory
storeInventory.put(sectionToStock, newValue);
System.out.printf("<%d> <%s> Assistant Finished Stocking Section %s = %d\n",tick.get(), Thread.currentThread().getId(),sectionToStock,storeInventory.get(sectionToStock));
}
//delete from inventory
inventory.put(sectionToStock, 0);
}
}
//Helper Function for stock
private int countNumsInInventory(Dictionary<String,Integer> inventory) {
int count = 0;
for (int val : ((Hashtable<String, Integer>) inventory).values()) {
count += val;
}
return count;
}
//Helper Function for Stock
private static boolean allValuesAreZero(Dictionary<String, Integer> map) {
for (int value : ((Hashtable<String, Integer>) map).values()) {
if (value != 0) {
return false;
}
}
return true;
}
//Prints the current store inventory...Used for Testing
public void printInventory(){
Enumeration<String> k = storeInventory.keys();
while (k.hasMoreElements()) {
String key = k.nextElement();
System.out.println("Key: " + key + ", Value: "
+ storeInventory.get(key));
}
}
//Primary Function of ThriftStore Object
//This function serves as the "tick" that all other threads look to do determine when to make their decisions
public void thriftStoreDay( AtomicInteger tick, int tickLength,int daysToRun){
while(tick.get() < (NUM_TICKS * daysToRun) ){
try{
Thread.sleep(tickLength);
}catch(InterruptedException e){
e.printStackTrace();
}
tick.getAndIncrement();
}
}
}
//Make Main class