-
Notifications
You must be signed in to change notification settings - Fork 0
/
LazyDentist.java
189 lines (169 loc) · 5.63 KB
/
LazyDentist.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import java.util.concurrent.Semaphore;
/**
* System has patient threads and a dentist thread
* There are N chairs for waiting patients in the dental clinic.
* If there are no free chairs, the patient leaves.
* If the dentist is sleeping, the patient wakes her up and consults her.
* Otherwise the patient takes a seat a waits.
* If the dentist finishes with a patient and there are waiting patients, then
* she takes the next patient. If there are no more patients, then she goes to sleep.
*
* @author mshortt and mkhan
*
* Answers to the blanks:
*
* Dentist blanks
* 1. Wait( patientReady )
* 2. Wait( seatCountWriteAccess )
* 3. Signal( dentistReady )
* 4. Signal( seatCountWriteAccess )
*
* Customer blanks
* 5. Wait( seatCountWriteAccess )
* 6. Signal( patientReady )
* 7. Signal( seatCountWriteAccess )
* 8. Wait( dentistReady )
* 9. Signal( seatCountWriteAccess )
*
*/
public class LazyDentist {
//Declare semaphores
//Semaphores for dentistReady and seatCountWriteAccess are mutexes (can only be 0 or 1)
//Semaphore for the dentist
Semaphore dentistReady = new Semaphore(0);
//Semaphore for accessing the number of seats in the waiting room
//if 1, the number of seats can be changed
Semaphore seatCountWriteAccess = new Semaphore(1);
//Semaphore for the number of waiting patients
Semaphore patientReady = new Semaphore(0);
//Instance variables
//Total number of seats in the waiting room
//For this example we are assuming that this will always be 3
int numberOfFreeWRSeats=3;
//An array of threads to hold the threads of the patients
Thread[] patients;
//The thread of the dentist
Thread dentist;
/**
* The main method
* This method takes in the number of patients (as one integer)
* and creates a new instance of the LazyDentist which calls all the logic
* for this exercise
*
* We have tested this with 1 patient, 2 patients, 3 patients, and 5 patients
*
* @param args - takes in one integer as the number of patients
*/
public static void main(String[] args) {
//check to make sure that the appropriate number of parameters were passed in
if(args.length != 1)
{
System.out.println("Please pass the number of patients as a parameter.");
System.exit(0);
}
//local variable for the number of patients (use 1 as a default value)
int numP = 1;
//try to parse the argument as an integer and throw an exception if it is not one
try {
numP = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.out.println("Please pass the number of patients as an integer.");
System.exit(0);
}
//creates an instance of LazyDentist with the number of patients passed
LazyDentist ld = new LazyDentist(numP);
}
/**
* Constructor for LazyDentist
* This method takes in the number of patients, initializes the dentist and the patient threads,
* and starts their execution
*
* @param numPatients
*/
public LazyDentist(int numPatients) {
//initialize dentist
initDentist();
//start dentist thread
dentist.start();
//initialize the length of the patient array
patients = new Thread[numPatients];
//initialize patients
for(int i=0; i < patients.length; i++)
{
initPatient(i+1);
}
//start patient threads
for(int i=0; i < patients.length; i++)
{
patients[i].start();
}
}
/**
* This method initializes the dentist's thread
*/
public void initDentist() {
dentist = new Thread(){
public void run() {
//run an infinite loop
while(true) {
try {
//try to acquire a patient (if none is available, dentist remains sleeping)
patientReady.acquire();
//try to get access to modify the number of available seats (if cannot, remain sleeping)
seatCountWriteAccess.acquire();
//increase the number of chairs free because the dentist is going to see a patient
numberOfFreeWRSeats += 1;
//the dentist is now ready to consult! Wake up!
dentistReady.release();
//release the lock of the chairs
seatCountWriteAccess.release();
//write to console that the dentist is talking to a patient
System.out.println("Dentist is talking to a patient.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
/**
* This method initializes the patients' threads, taking as a parameter the number of the patient
* @param patientNum - the number of the patient
*/
public void initPatient(final int patientNum) {
//the patient number starts at 1, so we have to subtract one for the index in the patient's thread array
patients[patientNum-1] = new Thread() {
public void run() {
//run in an infinite loop to simulate multiple patients
while(true) {
try {
//try to get access to the waiting room chairs
seatCountWriteAccess.acquire();
//if there are any free seats
if( numberOfFreeWRSeats > 0)
{
//sit down in a chair, meaning there is one less available
numberOfFreeWRSeats -= 1;
//notify the dentist that there is a patient
patientReady.release();
//release the lock of the seats
seatCountWriteAccess.release();
//wait until the dentist is ready
dentistReady.acquire();
//write to console that this patient is consulting the dentist
System.out.println("Patient "+patientNum+" is consulting with the dentist!");
}
//otherwise, if there are no free seats, then the patient leaves
else
{
//but before leaving the patient must give up the lock of the seats
seatCountWriteAccess.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
}