public Lock acquireSharedLock(int value) {
    final int index = index(value);

    if (useSpinLock) {
      OReadersWriterSpinLock spinLock = spinLocks[index];
      spinLock.acquireReadLock();

      return new SpinLockWrapper(true, spinLock);
    }

    final ReadWriteLock rwLock = locks[index];

    final Lock lock = rwLock.readLock();
    lock.lock();
    return lock;
  }
  @Override
  public Lock acquireSharedLock(final T value) {
    final int index;
    if (value == null) index = 0;
    else index = index(value.hashCode());

    if (useSpinLock) {
      OReadersWriterSpinLock spinLock = spinLocks[index];
      spinLock.acquireReadLock();

      return new SpinLockWrapper(true, spinLock);
    }

    final ReadWriteLock rwLock = locks[index];

    final Lock lock = rwLock.readLock();
    lock.lock();
    return lock;
  }