Esempio n. 1
0
  private long _competeIncrement(CounterRegister counterRegister, int size) throws SystemException {

    CounterHolder counterHolder = counterRegister.getCounterHolder();

    // Try to use the fast path

    long newValue = counterHolder.addAndGet(size);

    if (newValue <= counterHolder.getRangeMax()) {
      return newValue;
    }

    // Use the slow path

    CompeteLatch completeLatch = counterRegister.getCompeteLatch();

    if (!completeLatch.compete()) {

      // Loser thread has to wait for the winner thread to finish its job

      try {
        completeLatch.await();
      } catch (InterruptedException ie) {
        throw processException(ie);
      }

      // Compete again

      return _competeIncrement(counterRegister, size);
    }

    // Winner thread

    try {

      // Double check

      counterHolder = counterRegister.getCounterHolder();
      newValue = counterHolder.addAndGet(size);

      if (newValue > counterHolder.getRangeMax()) {
        CounterHolder newCounterHolder =
            _obtainIncrement(counterRegister.getName(), counterRegister.getRangeSize(), 0);

        newValue = newCounterHolder.addAndGet(size);

        counterRegister.setCounterHolder(newCounterHolder);
      }
    } catch (Exception e) {
      throw processException(e);
    } finally {

      // Winner thread opens the latch so that loser threads can continue

      completeLatch.done();
    }

    return newValue;
  }