All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.commons.util.concurrent.StripedCounters Maven / Gradle / Ivy

There is a newer version: 15.1.0.Dev04
Show newest version
package org.infinispan.commons.util.concurrent;

import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.function.Supplier;

import org.infinispan.commons.util.ProcessorInfo;

/**
 * Duplicates a set of counters in a set of stripes, so that multiple threads can increment those counters without too
 * much contention.
 * 

* Callers must first obtain a stripe for the current thread with {@link #stripeForCurrentThread()}, then use {@link * #increment(AtomicLongFieldUpdater, Object)} or {@link #add(AtomicLongFieldUpdater, Object, long)} to update one or * more counters in that stripe. They must also provide a {@link AtomicLongFieldUpdater} to access a specific counter in * the stripe - it should be defined as {@code static final} so that it can be inlined by the JIT. * * @author Dan Berindei * @since 9.0 */ public final class StripedCounters { private static final int STRIPE_COUNT = (int) (Long.highestOneBit(ProcessorInfo.availableProcessors()) << 1); private static final int STRIPE_MASK = STRIPE_COUNT - 1; @SuppressWarnings("unchecked") private final T[] stripes = (T[]) new Object[STRIPE_COUNT]; public StripedCounters(Supplier stripeSupplier) { for (int i = 0; i < stripes.length; i++) { stripes[i] = stripeSupplier.get(); } } public void increment(AtomicLongFieldUpdater updater, T stripe) { updater.getAndIncrement(stripe); } public void add(AtomicLongFieldUpdater updater, T stripe, long delta) { updater.getAndAdd(stripe, delta); } public long get(AtomicLongFieldUpdater updater) { long sum = 0; for (T stripe : stripes) { sum += updater.get(stripe); } return sum; } public void reset(AtomicLongFieldUpdater updater) { for (T stripe : stripes) { updater.set(stripe, 0); } } public T stripeForCurrentThread() { return stripes[threadIndex()]; } private int threadIndex() { // Spread the thread id a bit, in case it's always a multiple of 16 long id = Thread.currentThread().getId(); id ^= id >>> 7 ^ id >>> 4; return (int) (id & STRIPE_MASK); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy