-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrafficController.java
More file actions
executable file
·76 lines (69 loc) · 2.53 KB
/
TrafficController.java
File metadata and controls
executable file
·76 lines (69 loc) · 2.53 KB
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
/**
* TrafficController.java — single-lane bridge monitor.
*
* THREAD-SAFETY SUMMARY:
* - SYNCHRONIZED METHODS TURN THIS CLASS INTO A MONITOR SO ONLY ONE CAR THREAD
* CAN ENTER OR LEAVE AT A TIME WHILE MUTATING COUNTS.
* - wait()/notifyAll() PARK THREADS WHEN THE OPPOSITE COLOR IS ON THE BRIDGE
* AND WAKE THEM WHEN THE BRIDGE IS EMPTY, PREVENTING BUSY-WAITING.
* - redCarsOnBridge / blueCarsOnBridge TRACK OCCUPANCY UNDER THE SAME LOCK
* SO MUTUAL EXCLUSION IS ENFORCED EXACTLY ONCE.
*/
public class TrafficController {
// Number of red cars currently on the bridge
private int redCarsOnBridge = 0;
// Number of blue cars currently on the bridge
private int blueCarsOnBridge = 0;
/**
* ENTERLEFT IS SYNCHRONIZED SO ONLY ONE RED CAR THREAD CAN CHECK/MODIFY
* THE COUNTS AT A TIME, AND IT WAITS UNTIL BLUE CARS HAVE LEFT.
*/
public synchronized void enterLeft() {
// KEEP WAITING WHILE BLUE CARS ARE STILL CROSSING
while (blueCarsOnBridge > 0) {
try {
// WAIT RELEASES THE MONITOR LOCK SO BLUE CARS CAN CALL leaveLeft()
wait();
} catch (InterruptedException e) {
System.err.println("Red car thread interrupted");
}
}
// SAFE TO ENTER; UPDATE RED COUNT WHILE HOLDING THE LOCK
redCarsOnBridge++;
}
/**
* ENTERRIGHT MIRRORS ENTERLEFT FOR BLUE CARS USING THE SAME MONITOR LOCK
* AND wait()/notifyAll() PROTOCOL.
*/
public synchronized void enterRight() {
// KEEP WAITING WHILE RED CARS ARE STILL CROSSING
while (redCarsOnBridge > 0) {
try {
wait();
} catch (InterruptedException e) {
System.err.println("Blue car thread interrupted");
}
}
// SAFE TO ENTER; UPDATE BLUE COUNT ATOMICALLY
blueCarsOnBridge++;
}
/**
* LEAVELEFT IS SYNCHRONIZED SO ONLY ONE THREAD DECREMENTS THE BLUE COUNT
* AND IT CALLS notifyAll() WHEN THE BRIDGE BECOMES EMPTY TO WAKE RED CARS.
*/
public synchronized void leaveLeft() {
blueCarsOnBridge--;
if (blueCarsOnBridge == 0) {
notifyAll(); // SIGNAL THREADS BLOCKING IN ENTERLEFT/ENTERRIGHT
}
}
/**
* LEAVERIGHT DOES THE SAME FOR RED CARS, BROADCASTING WHEN THE BRIDGE CLEARS.
*/
public synchronized void leaveRight() {
redCarsOnBridge--;
if (redCarsOnBridge == 0) {
notifyAll(); // WAKE ANY BLUE CARS WAITING TO ENTER
}
}
}