In the code below is there a better implementation for the second synchronized block? The code is somehow inefficient. It calls notifyAll but makes no difference as calling notify. is it better for the code to call notifyAll or notify?
The code is an example of using the Scheduler design pattern. Thanks in advance
class Printer {
private Scheduler scheduler = new Scheduler();
public void print(JournalEntry j) {
try {
scheduler.enter(j);
try {
//...
} finally {
scheduler.done();
} // try
} catch (InterruptedException e) {
} //try
} // print(JournalEntry)
} // class Printer
public class Scheduler {
private Thread runningThread;
private ArrayList waitingRequests = new ArrayList();
private ArrayList waitingThreads = new ArrayList();
public void enter(ScheduleOrdering s) throws InterruptedException {
Thread thisThread = Thread.currentThread();
synchronized (this) {
if (runningThread == null) {
runningThread = thisThread;
return;
} // if
waitingThreads.add(thisThread);
waitingRequests.add(s);
} // synchronized (this)
synchronized (thisThread) {
while (thisThread != runningThread) {
thisThread.wait();
} // while
} // synchronized (thisThread)
synchronized (this) {
int i = waitingThreads.indexOf(thisThread);
waitingThreads.remove(i);
waitingRequests.remove(i);
} // synchronized (this)
} // enter(ScheduleOrdering)
synchronized public void done() {
if (runningThread != Thread.currentThread())
throw new IllegalStateException("Wrong Thread");
int waitCount = waitingThreads.size();
if (waitCount <= 0) {
runningThread = null;
} else if (waitCount == 1) {
runningThread = (Thread)waitingThreads.get(0);
} else {
int next = waitCount - 1;
ScheduleOrdering nextRequest;
nextRequest = (ScheduleOrdering)waitingRequests.get(next);
for (int i = waitCount-2; i>=0; i--) {
ScheduleOrdering r;
r = (ScheduleOrdering)waitingRequests.get(i);
if (r.scheduleBefore(nextRequest)) {
next = i;
nextRequest = (ScheduleOrdering)waitingRequests.get(next);
} // if
} // for
runningThread = (Thread)waitingThreads.get(next);
} // if waitCount
synchronized (runningThread) {
runningThread.notifyAll();
} // synchronized (runningThread)
} // done()
} // class Scheduler```
Aucun commentaire:
Enregistrer un commentaire