android/guava/src/com/google/common/collect/ConcurrentHashMultiset.java
@CanIgnoreReturnValue
  @Override
  public int add(E element, int occurrences) {
    checkNotNull(element);
    if (occurrences == 0) {
      return count(element);
    }
    CollectPreconditions.checkPositive(occurrences, "occurences");

    while (true) {
      AtomicInteger existingCounter = Maps.safeGet(countMap, element);
      if (existingCounter == null) {
        existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences));
        if (existingCounter == null) {
          return 0;
        }
        // existingCounter != null: fall through to operate against the existing AtomicInteger
      }

      while (true) {
        int oldValue = existingCounter.get();
        if (oldValue != 0) {
          try {
            int newValue = IntMath.checkedAdd(oldValue, occurrences);
            if (existingCounter.compareAndSet(oldValue, newValue)) {
              // newValue can't == 0, so no need to check & remove
              return oldValue;
            }
          } catch (ArithmeticException overflow) {
            throw new IllegalArgumentException(
                "Overflow adding " + occurrences + " occurrences to a count of " + oldValue);
          }
        } else {
          // In the case of a concurrent remove, we might observe a zero value, which means another
          // thread is about to remove (element, existingCounter) from the map. Rather than wait,
          // we can just do that work here.
          AtomicInteger newCounter = new AtomicInteger(occurrences);
          if ((countMap.putIfAbsent(element, newCounter) == null)
              || countMap.replace(element, existingCounter, newCounter)) {
            return 0;
          }
          break;
        }
      }

      // If we're still here, there was a race, so just try again.
    }
  }
@CanIgnoreReturnValue
  @Override
  public int add(E element, int occurrences) {
    checkNotNull(element);
    if (occurrences == 0) {
      return count(element);
    }
    CollectPreconditions.checkPositive(occurrences, "occurences");

    while (true) {
      AtomicInteger existingCounter = Maps.safeGet(countMap, element);
      if (existingCounter == null) {
        existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences));
        if (existingCounter == null) {
          return 0;
        }
        // existingCounter != null: fall through to operate against the existing AtomicInteger
      }

      while (true) {
        int oldValue = existingCounter.get();
        if (oldValue != 0) {
          try {
            int newValue = IntMath.checkedAdd(oldValue, occurrences);
            if (existingCounter.compareAndSet(oldValue, newValue)) {
              // newValue can't == 0, so no need to check & remove
              return oldValue;
            }
          } catch (ArithmeticException overflow) {
            throw new IllegalArgumentException(
                "Overflow adding " + occurrences + " occurrences to a count of " + oldValue);
          }
        } else {
          // In the case of a concurrent remove, we might observe a zero value, which means another
          // thread is about to remove (element, existingCounter) from the map. Rather than wait,
          // we can just do that work here.
          AtomicInteger newCounter = new AtomicInteger(occurrences);
          if ((countMap.putIfAbsent(element, newCounter) == null)
              || countMap.replace(element, existingCounter, newCounter)) {
            return 0;
          }
          break;
        }
      }

      // If we're still here, there was a race, so just try again.
    }
  }
@ CanIgnoreReturnValue @ Override public int add ( E element , int occurrences ) { checkNotNull ( element ) ; if ( occurrences == 0 ) { return count ( element ) ; } CollectPreconditions . checkPositive ( occurrences , "occurences" ) ; while ( true ) { AtomicInteger existingCounter = Maps . safeGet ( countMap , element ) ; if ( existingCounter == null ) { existingCounter = countMap . putIfAbsent ( element , new AtomicInteger ( occurrences ) ) ; if ( existingCounter == null ) { return 0 ; } // existingCounter != null: fall through to operate against the existing AtomicInteger } while ( true ) { int oldValue = existingCounter . get ( ) ; if ( oldValue != 0 ) { try { int newValue = IntMath . checkedAdd ( oldValue , occurrences ) ; if ( existingCounter . compareAndSet ( oldValue , newValue ) ) { // newValue can't == 0, so no need to check & remove return oldValue ; } } catch ( ArithmeticException overflow ) { throw new IllegalArgumentException ( "Overflow adding " + occurrences + " occurrences to a count of " + oldValue ) ; } } else { // In the case of a concurrent remove, we might observe a zero value, which means another // thread is about to remove (element, existingCounter) from the map. Rather than wait, // we can just do that work here. AtomicInteger newCounter = new AtomicInteger ( occurrences ) ; if ( ( countMap . putIfAbsent ( element , newCounter ) == null ) || countMap . replace ( element , existingCounter , newCounter ) ) { return 0 ; } break ; } } // If we're still here, there was a race, so just try again. } }
Adds a number of occurrences of the specified element to this multiset.

@param element the element to add
@param occurrences the number of occurrences to add
@return the previous count of the element before the operation; possibly zero
@throws IllegalArgumentException if {@code occurrences} is negative, or if the resulting amount
would exceed {@link Integer#MAX_VALUE}
Adds a number of occurrences of the specified element to this multiset .