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; }
public Object get(Serializable key) { Object value = _portalCache.get(key); if (value != null) { return value; } CompeteLatch lastCompeteLatch = _competeLatch.get(); if (lastCompeteLatch != null) { lastCompeteLatch.done(); _competeLatch.set(null); } CompeteLatch currentCompeteLatch = _competeLatchMap.get(key); if (currentCompeteLatch == null) { CompeteLatch newCompeteLatch = new CompeteLatch(); currentCompeteLatch = _competeLatchMap.putIfAbsent(key, newCompeteLatch); if (currentCompeteLatch == null) { currentCompeteLatch = newCompeteLatch; } } _competeLatch.set(currentCompeteLatch); if (!currentCompeteLatch.compete()) { try { currentCompeteLatch.await(); } catch (InterruptedException ie) { } _competeLatch.set(null); value = _portalCache.get(key); } return value; }