예제 #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;
  }
예제 #2
0
  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;
  }