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; }