synchronized void transactionServiced(TransactionQueueEvent event) {
    TransactionQueueEvent svcEvent = new TransactionQueueEvent(event);

    mTotalServiceDuration += (svcEvent.getTimestampMillis() - event.getTimestampMillis());

    if (mListeners.size() > 0) {
      Iterator it = mListeners.iterator();
      while (it.hasNext()) {
        ((TransactionQueueListener) it.next()).transactionServiced(svcEvent);
      }
    }

    // Adjust counters at end in case a listener threw an exception and let
    // the call to transactionException adjust the counters instead.
    mServicingCount--;
    mTotalServiced++;
  }
  synchronized TransactionQueueEvent transactionDequeued(TransactionQueueEvent event) {

    if (++mServicingCount > mPeakServicingCount) {
      mPeakServicingCount = mServicingCount;
    }

    TransactionQueueEvent deqEvent = new TransactionQueueEvent(event);

    mTotalQueueDuration += (deqEvent.getTimestampMillis() - event.getTimestampMillis());

    if (mListeners.size() > 0) {
      Iterator it = mListeners.iterator();
      while (it.hasNext()) {
        ((TransactionQueueListener) it.next()).transactionDequeued(deqEvent);
      }
    }

    return deqEvent;
  }
    public void run() {
      boolean forceExit = false;
      TransactionQueueEvent event;

      while (true) {
        try {
          // allow event to be GC'd in case we wait() on next event
          event = null;

          // Phase 1: wait for a transaction
          try {
            if ((event = nextTransactionEvent()) == null) {
              // Go into idle mode.
              continue;
            }
          } catch (InterruptedException e) {
            forceExit = true;
            continue;
          }

          long enqueueTimestamp = event.getTimestampMillis();

          // Phase 2: spawn off a replacement thread
          try {
            startThread(false);
          } catch (NoThreadException e) {
            if (e.isThreadPoolClosed()) {
              forceExit = true;
              // Don't "continue" because the transaction must
              // still be serviced first.
            }
          } catch (InterruptedException e) {
            forceExit = true;
            // Don't "continue" because the transaction must
            // still be serviced first.
          } catch (Throwable e) {
            uncaughtException(e);
          } finally {
            // Only indicate that transaction has been dequeued
            // after a replacement thread has been created.
            // Queue time is more accurate this way because time
            // spent waiting for a thread is time spent not being
            // serviced.
            try {
              event = transactionDequeued(event);
            } catch (Throwable e) {
              uncaughtException(e);
            }
          }

          long serviceTimestamp = event.getTimestampMillis();

          // Phase 3: service the transaction
          long timeout = getTransactionTimeout();
          if (timeout >= 0 && (serviceTimestamp - enqueueTimestamp) >= timeout) {
            try {
              event.getTransaction().cancel();
            } finally {
              transactionExpired(event);
            }
          } else {
            try {
              event.getTransaction().service();
              transactionServiced(event);
            } catch (Throwable e) {
              uncaughtException(e);

              try {
                event.getTransaction().cancel();
              } catch (Throwable e2) {
                uncaughtException(e2);
              }

              transactionException(event, e);
            }
          }
        } catch (Throwable e) {
          try {
            uncaughtException(e);
          } catch (Throwable e2) {
            // If another error is thrown while trying to log the
            // first error, ignore it. This ensures that the
            // exitThread method is called, even if
            // OutOfMemoryErrors are being thrown around.
          }
        } finally {
          if (exitThread(forceExit)) {
            break;
          }
        }
      }
    }