private void schedule() {
   queueSize.acquireUninterruptibly();
   for (Map.Entry<String, WeightedQueue> request : queues.entrySet()) {
     WeightedQueue queue = request.getValue();
     // Using the weight, process that many requests at a time (for that scheduler id)
     for (int i = 0; i < queue.weight; i++) {
       Thread t = queue.poll();
       if (t == null) break;
       else {
         taskCount.acquireUninterruptibly();
         queueSize.acquireUninterruptibly();
       }
     }
   }
   queueSize.release();
 }
  /*
   * Get the Queue for the respective id, if one is not available
   * create a new queue for that corresponding id and return it
   */
  private WeightedQueue getWeightedQueue(String id) {
    WeightedQueue weightedQueue = queues.get(id);
    if (weightedQueue != null)
      // queue existed
      return weightedQueue;

    WeightedQueue maybenew = new WeightedQueue(id, getWeight(id));
    weightedQueue = queues.putIfAbsent(id, maybenew);
    if (weightedQueue == null) {
      // created new queue: register for monitoring
      maybenew.register();
      return maybenew;
    }

    // another thread created the queue
    return weightedQueue;
  }
  public void queue(Thread t, String id, long timeoutMS) throws TimeoutException {
    WeightedQueue weightedQueue = getWeightedQueue(id);

    try {
      queueSize.release();
      try {
        weightedQueue.put(t, timeoutMS);
        // the scheduler will release us when a slot is available
      } catch (TimeoutException e) {
        queueSize.acquireUninterruptibly();
        throw e;
      } catch (InterruptedException e) {
        queueSize.acquireUninterruptibly();
        throw e;
      }
    } catch (InterruptedException e) {
      throw new RuntimeException("Interrupted while queueing requests", e);
    }
  }