public int compare(TickActer a, TickActer b) {
   if (a == b) return 0;
   int i =
       (int)
           (a.nextAct()
               - b
                   .nextAct()); // lower value == lower time to go == lower in queue ==
                                // higher priority
   return (i == 0 ? 1 : i);
 }
 public void startTickDown(TickActer E) {
   if (E.nextAct() <= System.currentTimeMillis()) {
     CMClass.threadPool.execute(E);
     return;
   }
   tickActQueue.add(E);
   if (tickActQueue.first() == E) tickActThread.interrupt();
 }
 public void run() {
   while (true) {
     try {
       while (!tickActQueue.isEmpty()) {
         awake = false;
         TickActer next = tickActQueue.first();
         long timeToSleep = next.nextAct() - System.currentTimeMillis();
         if (timeToSleep > 0) Thread.sleep(timeToSleep);
         awake = true;
         nextTicker:
         if ((CMProps.Bools.MUDSTARTED.property()) && (!isSuspended)) {
           if (!tickActQueue.remove(next)) break nextTicker;
           CMClass.threadPool.execute(next);
         }
       }
     }
     /*try { next.tickAct(); }
     catch(Exception t) { Log.errOut("ServiceEngine",t); }*/
     catch (InterruptedException ioe) {
     }
     // If it was interrupted, it is most likely because we need to wake up for a new early
     // ticker, or the previous new ticker got baleeted.
     // Interruptions will only come if the thread is sleeping though.
     // NOTE: tickAct() should NEVER call a sleep (nor take any significant amount of time
     // anyways)!
     if (dead) {
       awake = false;
       break;
     }
     synchronized (tickActQueue) {
       while (tickActQueue.isEmpty())
         try {
           tickActQueue.wait();
         } catch (InterruptedException ioe) {
         }
     }
   }
 }