-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLaserPrinter.java
executable file
·174 lines (155 loc) · 6.37 KB
/
LaserPrinter.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
/*
Author: Senthuran Ambalavanar | 2015215 | w1608452
*/
import utils.LoggerProcess;
import utils.Utility;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Represents the laser printer resource, which is shared within the printing system
*/
public class LaserPrinter implements ServicePrinter {
private String printerId;
private int paperLevel;
private int tonerLevel;
private int noOfDocumentsPrinted;
private ThreadGroup userGroup;
// Reentrant lock with fairness enabled
private Lock lock = new ReentrantLock(true);
private Condition condition = lock.newCondition();
public LaserPrinter(String printerId, ThreadGroup userGroup) {
this.printerId = printerId;
this.paperLevel = Full_Paper_Tray;
this.tonerLevel = Full_Toner_Level;
this.noOfDocumentsPrinted = 0;
this.userGroup = userGroup;
}
@Override
public void replaceTonerCartridge() {
lock.lock();
try {
// Repeatedly check for the need to replace toner cartridge, in 5 seconds time interval
while (tonerLevel > Minimum_Toner_Level) {
// Check if printer has finished serving all the userGroup
if (isPrinterUsageComplete()) {
Utility.log(
LoggerProcess.PRINTER,
"Usage of the printer is complete. No need to replace toner cartridge",
false);
break;
} else {
Utility.log(LoggerProcess.PRINTER, toString(), null);
Utility.log(
LoggerProcess.PRINTER,
"Toner has not reached the minimum level to be refilled. Waiting to check again",
false);
condition.await(5, TimeUnit.SECONDS);
}
}
// Replace toner cartridge if necessary
if (tonerLevel < Minimum_Toner_Level) {
tonerLevel = Full_Toner_Level;
Utility.log(
LoggerProcess.PRINTER,
"Replaced toner cartridge",
true);
Utility.log(LoggerProcess.PRINTER, toString(), null);
}
condition.signalAll();
} catch (InterruptedException e) {
Utility.log(LoggerProcess.PRINTER, e.toString(), false);
} finally {
lock.unlock();
}
}
@Override
public void refillPaper() {
lock.lock();
try {
// Repeatedly check for the need to refill paper, in 5 seconds time interval
while (paperLevel + SheetsPerPack > Full_Paper_Tray) {
if (isPrinterUsageComplete()) {
Utility.log(
LoggerProcess.PRINTER,
"Usage of the printer is complete. No need to refill paper",
false);
break;
} else {
Utility.log(LoggerProcess.PRINTER, toString(), null);
Utility.log(
LoggerProcess.PRINTER,
"Refilling paper will exceed the capacity. Waiting to check again",
false);
condition.await(5, TimeUnit.SECONDS);
}
}
// Refill paper if necessary
if (paperLevel + SheetsPerPack <= Full_Paper_Tray) {
paperLevel += SheetsPerPack;
Utility.log(
LoggerProcess.PRINTER,
"Refilled paper",
true);
Utility.log(LoggerProcess.PRINTER, toString(), null);
}
condition.signalAll();
} catch (InterruptedException e) {
Utility.log(LoggerProcess.PRINTER, e.toString(), false);
} finally {
lock.unlock();
}
}
@Override
public void printDocument(Document document) {
lock.lock();
try {
Utility.log(LoggerProcess.PRINTER, toString(), null);
// When resources are insufficient, wait until resources become sufficient
while (paperLevel < document.getNumberOfPages() || tonerLevel < document.getNumberOfPages()) {
String message;
if (paperLevel < document.getNumberOfPages()) {
message = "Insufficient Papers. Waiting until refilled";
} else if (tonerLevel < document.getNumberOfPages()) {
message = "Insufficient Toner level. Waiting until cartridge is replaced";
} else {
message = "Insufficient Papers & Toner level. Waiting until they become available";
}
Utility.log(LoggerProcess.PRINTER, message, false);
condition.await();
}
// Print document if resources are sufficient
if (paperLevel >= document.getNumberOfPages() && tonerLevel >= document.getNumberOfPages()) {
paperLevel -= document.getNumberOfPages();
tonerLevel -= document.getNumberOfPages();
noOfDocumentsPrinted++;
Utility.log(
LoggerProcess.PRINTER,
"Printed document: " + document, true);
Utility.log(LoggerProcess.PRINTER, toString(), null);
}
condition.signalAll();
} catch (InterruptedException e) {
Utility.log(LoggerProcess.PRINTER, e.toString(), false);
} finally {
lock.unlock();
}
}
@Override
public String toString() {
return "[ PrinterID: " + printerId +
", Paper Level: " + paperLevel +
", Toner Level: " + tonerLevel +
", Documents Printed: " + noOfDocumentsPrinted + " ]";
}
/**
* Checks whether the usage of the printer is over,
* in order to avoid waiting in time intervals and re-checking for replacing toner cartridge / refilling paper
*
* @return Whether the usage of the printer is over or not
*/
private boolean isPrinterUsageComplete() {
return userGroup.activeCount() == 0;
}
}