1
+ /*
2
+ @author Josh Braden
3
+ This program is a peek into facutly life in the SHSU CS department.
4
+ Simulates a *realistic* candy bowl with *lifelike* faculty members.
5
+ The bowl can only be accessed by one member at a time, exemplifying usage syncronized methods in Java.
6
+ The program supports N bowls, professors, and TA's, but only one list of each is allowed.
7
+ So no support for access control lists.
8
+ CLASS LIST
9
+ ==============================================
10
+ Bowl
11
+ Professor
12
+ TA
13
+ main
14
+ */
15
+
16
+ import java .util .Random ;
17
+ import java .util .Scanner ;
18
+
19
+ /*
20
+ Bowl Class: has a current and max number of candies.
21
+ The bowl has two methods associated with it: get and fill
22
+ Get gets a piece of candy from the bowl
23
+ Fill fills it back up (presumably by a TA)
24
+ Bowl also has an ID to differentiate between multiple bowls.
25
+ Get and Fill are both synchronized methods because only one person can access it at a time.
26
+ */
27
+ class Bowl {
28
+ //Variables
29
+ private int PieceKnt , MaxPieces , id ;
30
+ //Constructor: sets bowl size and does initial fill.
31
+ Bowl (int MaxPieces , int id ) {
32
+ this .MaxPieces = MaxPieces ;
33
+ PieceKnt = MaxPieces ;
34
+ this .id = id ;
35
+ }
36
+ //Get a candy from the bowl
37
+ synchronized public boolean Get () {
38
+ if (PieceKnt > 0 ) {
39
+ PieceKnt --;
40
+ System .out .println ("Bowl " + id + " has " + PieceKnt + " candy left" );
41
+ notifyAll ();
42
+ return true ;
43
+ } else {
44
+ notifyAll ();
45
+ return false ;
46
+ }
47
+ }
48
+ //Fills bowl back up (even if it's not empty theoretically)
49
+ synchronized public void Fill () {
50
+ PieceKnt = MaxPieces ;
51
+ System .out .println ("The bowl is full." );
52
+ notifyAll ();
53
+ }
54
+ }
55
+
56
+ /*
57
+ Professor class
58
+ Alternates between sleeping and eating candy, just like real life.
59
+ Unlike Bowl, which is just a shared data structure, Professors are living and breathing.
60
+ Therefore, they are extentions of Thread
61
+ Professors get candy from the Bowl object 'target'
62
+ Professors are also assigned to a TA, so they can offload the demanding task of filling the bowl to a younger body.
63
+ */
64
+ class Professor extends Thread {
65
+ //Variables
66
+ private Bowl [] BowlList ;
67
+ private TA [] TAList ;
68
+ private String name ;
69
+ private Random rng = new Random ();
70
+ private int KandyKnt , MaxSleep , SleepTime , target , BowlKnt , TAKnt ;
71
+ private boolean GetStatus ;
72
+
73
+ //Contructor method: set local variables
74
+ Professor (Bowl [] BowlList , TA [] TAList , int MaxSleep , String name ) {
75
+ this .BowlList = BowlList ;
76
+ BowlKnt = BowlList .length ;
77
+ this .TAList = TAList ;
78
+ TAKnt = TAList .length ;
79
+ this .MaxSleep = MaxSleep ;
80
+ this .name = name ;
81
+ KandyKnt = 0 ;
82
+ }
83
+
84
+ //Method that gets run as a thread
85
+ public void run () {
86
+ try {
87
+ //Infinite loop of sleeping and eating
88
+ while (true ) {
89
+ //Select a bowl to Get from and do Get
90
+ target = rng .nextInt (BowlKnt );
91
+ GetStatus = BowlList [target ].Get ();
92
+ if (GetStatus == false ) {
93
+ //Bowl empty, needs filling. Select a TA and tell them to fill the bowl.
94
+ TAList [rng .nextInt (TAKnt )].FillBowl (target );
95
+ } else {
96
+ KandyKnt ++;
97
+ //Proceed to sleep
98
+ SleepTime = rng .nextInt (MaxSleep );
99
+ System .out .println (name + " has consumed a candy and sleeps for " + SleepTime + "ms." );
100
+ Thread .sleep (SleepTime );
101
+ }
102
+ }
103
+ } catch (InterruptedException e ) {
104
+
105
+ } finally {
106
+ //But before going away, tell everyone how awesome you are.
107
+ System .out .println (name + " ate " + KandyKnt + " pieces of candy." );
108
+ }
109
+ }
110
+ }
111
+
112
+ /*
113
+ TA class
114
+ A TA simply sits around and does nothing until someone tells them to fill up the candy bowl.
115
+ They could probably do other things too, but don't push it.
116
+ */
117
+ class TA {
118
+ //Variables
119
+ private Bowl [] BowlList ;
120
+ private String name ;
121
+
122
+ //Constructor: sets target, name and empty fill count
123
+ TA (Bowl [] BowlList , String name ) {
124
+ this .BowlList = BowlList ;
125
+ this .name = name ;
126
+ }
127
+
128
+ //This method defines the meaning of existance
129
+ public void FillBowl (int target ) {
130
+ BowlList [target ].Fill ();
131
+ System .out .println (name + " has filled bowl " + target );
132
+ }
133
+ }
134
+
135
+ /*
136
+ Main class, start here.
137
+ This class handles runtime options and execution
138
+ */
139
+ public class CandyBowl1 {
140
+ private static Scanner input = new Scanner (System .in );
141
+ public static void main (String [] args ) {
142
+ //Main Start
143
+ //Variables
144
+ int menuoption = 1 ;
145
+ //User decision input plus case structure
146
+ System .out .println ("Runtime options\n ===============\n 1) Use default parameters (SHSU CS Staff, 1 TA, 1 candy bowl)\n 2) Enumerate N objects" );
147
+ System .out .print ("Enter option: " );
148
+ menuoption = input .nextInt ();
149
+ switch (menuoption ) {
150
+ case 1 :
151
+ DefaultParams ();
152
+ break ;
153
+ case 2 :
154
+ EnumParams ();
155
+ break ;
156
+ default :
157
+ System .out .println ("Bad option entered, using default parameters" );
158
+ DefaultParams ();
159
+ break ;
160
+ }
161
+ }
162
+
163
+ //Default Parameter execution
164
+ private static void DefaultParams () {
165
+ //Set up default data
166
+ String [] Names = {
167
+ "Dr. Cooper" ,
168
+ "Dr. Burris" ,
169
+ "Dr. Smith" ,
170
+ "Dr. McGuire" ,
171
+ "Dr. Cho"
172
+ };
173
+ int SleepTime ;
174
+ Bowl [] Bowls = new Bowl [1 ];
175
+ Bowls [0 ] = new Bowl (20 , 0 );
176
+ TA [] TAs = new TA [1 ];
177
+ TAs [0 ] = new TA (Bowls , "Steve the TA" );
178
+ Professor [] Professors = new Professor [5 ];
179
+ SleepTime = 800 ; //CHANGE THIS TO CHANGE DEFAULT SLEEP TIME
180
+ for (int i = 0 ; i < 5 ; i ++) {
181
+ Professors [i ] = new Professor (Bowls , TAs , SleepTime , Names [i ]);
182
+ }
183
+ for (int i = 0 ; i < 5 ; i ++) {
184
+ Professors [i ].start ();
185
+ }
186
+ }
187
+
188
+ //Enumeration Parameter input and execution
189
+ private static void EnumParams () {
190
+ int ProfKnt , TAKnt , BowlKnt , PieceKnt , SleepTime , menuoption , RunTime ;
191
+ String Name ;
192
+ //Get user input values
193
+ System .out .print ("Enter number of professors: " );
194
+ ProfKnt = input .nextInt ();
195
+ System .out .print ("Enter number of TAs: " );
196
+ TAKnt = input .nextInt ();
197
+ System .out .print ("Enter number of candy bowls: " );
198
+ BowlKnt = input .nextInt ();
199
+ System .out .print ("Enter bowl capacity: " );
200
+ PieceKnt = input .nextInt ();
201
+ System .out .print ("Enter max sleep time (in ms, global): " );
202
+ SleepTime = input .nextInt ();
203
+ //Generate data to use for process
204
+ Bowl [] Bowls = new Bowl [BowlKnt ];
205
+ for (int i = 0 ; i < BowlKnt ; i ++) {
206
+ Bowls [i ] = new Bowl (PieceKnt , i );
207
+ }
208
+ TA [] TAs = new TA [TAKnt ];
209
+ for (int i = 0 ; i < TAKnt ; i ++) {
210
+ Name = "TA" + i ;
211
+ TAs [i ] = new TA (Bowls , Name );
212
+ }
213
+ Professor [] Professors = new Professor [ProfKnt ];
214
+ for (int i = 0 ; i < ProfKnt ; i ++) {
215
+ Name = "Professor" + i ;
216
+ Professors [i ] = new Professor (Bowls , TAs , SleepTime , Name );
217
+ }
218
+ //Get runtime parameters
219
+ System .out .println ("Select runtime option\n ===============\n 1) Run forever\n 2) Enter runtime" );
220
+ System .out .print ("Enter selection: " );
221
+ menuoption = input .nextInt ();
222
+ switch (menuoption ) {
223
+ case 1 : //start threads
224
+ for (int i = 0 ; i < ProfKnt ; i ++) {
225
+ Professors [i ].start ();
226
+ }
227
+ break ;
228
+ case 2 : //Get runtime length
229
+ System .out .print ("Enter runtime is ms: " );
230
+ RunTime = input .nextInt ();
231
+ //Start threads
232
+ for (int i = 0 ; i < ProfKnt ; i ++) {
233
+ Professors [i ].start ();
234
+ }
235
+ //Sleep for this much time then exit the threads
236
+ try {
237
+ Thread .sleep (RunTime );
238
+ System .out .println ("Time's up!" );
239
+ for (int i = 0 ; i < ProfKnt ; i ++) {
240
+ Professors [i ].interrupt ();
241
+ }
242
+ } catch (InterruptedException e ) {
243
+
244
+ }
245
+ break ;
246
+ default :
247
+ System .out .println ("Bad option entered, running forever" );
248
+ for (int i = 0 ; i < ProfKnt ; i ++) {
249
+ Professors [i ].start ();
250
+ }
251
+ break ;
252
+ }
253
+ }
254
+ }
0 commit comments