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 void remove(Serializable key) { _portalCache.remove(key); CompeteLatch competeLatch = _competeLatchMap.remove(key); if (competeLatch != null) { competeLatch.done(); } }
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; }
public void put(Serializable key, Object value) { if (key == null) { throw new IllegalArgumentException("Key is null"); } if (value == null) { throw new IllegalArgumentException("Value is null"); } _portalCache.put(key, value); CompeteLatch competeLatch = _competeLatch.get(); if (competeLatch != null) { competeLatch.done(); _competeLatch.set(null); } _competeLatchMap.remove(key); }