dimanche 11 avril 2021

Scheduler design Pattern code improvement

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