@Test public void testStripingDistribution() { int[] lockIndexes = new int[2048]; for (int i = 0; i < 20480 * 3; i++) { String key = "" + i * 3 / 2 + i; key += key.hashCode(); int lock = ConcurrencyUtil.selectLock(key, 2048); lockIndexes[lock]++; } int outliers = 0; for (int i = 0; i < 2048; i++) { if (20 <= lockIndexes[i] && lockIndexes[i] <= 40) { continue; } LOG.info(i + ": " + lockIndexes[i]); outliers++; } assertTrue(outliers <= 128); }
public static int selectLock(final Object key, int numberOfLocks) throws CacheException { int number = numberOfLocks & (numberOfLocks - 1); if (number != 0) { throw new CacheException("Lock number must be a power of two: " + numberOfLocks); } if (key == null) { return 0; } else { int hash = hash(key) & (numberOfLocks - 1); return hash; } }
ConcurrencyUtil { public static int selectLock(final Object key, int numberOfLocks) throws CacheException { int number = numberOfLocks & (numberOfLocks - 1); if (number != 0) { throw new CacheException("Lock number must be a power of two: " + numberOfLocks); } if (key == null) { return 0; } else { int hash = hash(key) & (numberOfLocks - 1); return hash; } } }
ConcurrencyUtil { public static int selectLock(final Object key, int numberOfLocks) throws CacheException { int number = numberOfLocks & (numberOfLocks - 1); if (number != 0) { throw new CacheException("Lock number must be a power of two: " + numberOfLocks); } if (key == null) { return 0; } else { int hash = hash(key) & (numberOfLocks - 1); return hash; } } private  ConcurrencyUtil(); }
ConcurrencyUtil { public static int selectLock(final Object key, int numberOfLocks) throws CacheException { int number = numberOfLocks & (numberOfLocks - 1); if (number != 0) { throw new CacheException("Lock number must be a power of two: " + numberOfLocks); } if (key == null) { return 0; } else { int hash = hash(key) & (numberOfLocks - 1); return hash; } } private  ConcurrencyUtil(); static int hash(Object object); static int selectLock(final Object key, int numberOfLocks); static void shutdownAndWaitForTermination(ExecutorService pool, int waitSeconds); }
ConcurrencyUtil { public static int selectLock(final Object key, int numberOfLocks) throws CacheException { int number = numberOfLocks & (numberOfLocks - 1); if (number != 0) { throw new CacheException("Lock number must be a power of two: " + numberOfLocks); } if (key == null) { return 0; } else { int hash = hash(key) & (numberOfLocks - 1); return hash; } } private  ConcurrencyUtil(); static int hash(Object object); static int selectLock(final Object key, int numberOfLocks); static void shutdownAndWaitForTermination(ExecutorService pool, int waitSeconds);  }