001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.util;
019
020import java.util.concurrent.locks.ReentrantReadWriteLock;
021import org.apache.yetus.audience.InterfaceAudience;
022
023/**
024 * Allows multiple concurrent clients to lock on a numeric id with ReentrantReadWriteLock. The
025 * intended usage for read lock is as follows:
026 *
027 * <pre>
028 * ReentrantReadWriteLock lock = idReadWriteLock.getLock(id);
029 * try {
030 *   lock.readLock().lock();
031 *   // User code.
032 * } finally {
033 *   lock.readLock().unlock();
034 * }
035 * </pre>
036 *
037 * For write lock, use lock.writeLock()
038 */
039@InterfaceAudience.Private
040public abstract class IdReadWriteLock<T> {
041  public abstract ReentrantReadWriteLock getLock(T id);
042
043  public void waitForWaiters(T id, int numWaiters) throws InterruptedException {
044    for (ReentrantReadWriteLock readWriteLock;;) {
045      readWriteLock = getLock(id);
046      if (readWriteLock != null) {
047        synchronized (readWriteLock) {
048          if (readWriteLock.getQueueLength() >= numWaiters) {
049            return;
050          }
051        }
052      }
053      Thread.sleep(50);
054    }
055  }
056}