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.ReentrantLock; 021import org.apache.hadoop.hbase.HBaseClassTestRule; 022import org.apache.hadoop.hbase.testclassification.MiscTests; 023import org.apache.hadoop.hbase.testclassification.SmallTests; 024import org.junit.Assert; 025import org.junit.ClassRule; 026import org.junit.Test; 027import org.junit.experimental.categories.Category; 028 029@Category({ MiscTests.class, SmallTests.class }) 030public class TestKeyLocker { 031 032 @ClassRule 033 public static final HBaseClassTestRule CLASS_RULE = 034 HBaseClassTestRule.forClass(TestKeyLocker.class); 035 036 @Test 037 public void testLocker() { 038 KeyLocker<String> locker = new KeyLocker<>(); 039 ReentrantLock lock1 = locker.acquireLock("l1"); 040 Assert.assertTrue(lock1.isHeldByCurrentThread()); 041 042 ReentrantLock lock2 = locker.acquireLock("l2"); 043 Assert.assertTrue(lock2.isHeldByCurrentThread()); 044 Assert.assertTrue(lock1 != lock2); 045 046 // same key = same lock 047 ReentrantLock lock20 = locker.acquireLock("l2"); 048 Assert.assertTrue(lock20 == lock2); 049 Assert.assertTrue(lock2.isHeldByCurrentThread()); 050 Assert.assertTrue(lock20.isHeldByCurrentThread()); 051 052 // Locks are still reentrant; so with 2 acquires we want two unlocks 053 lock20.unlock(); 054 Assert.assertTrue(lock20.isHeldByCurrentThread()); 055 056 lock2.unlock(); 057 Assert.assertFalse(lock20.isHeldByCurrentThread()); 058 059 // The lock object will be garbage-collected 060 // if you free its reference for a long time, 061 // and you will get a new one at the next time. 062 int lock2Hash = System.identityHashCode(lock2); 063 lock2 = null; 064 lock20 = null; 065 066 System.gc(); 067 System.gc(); 068 System.gc(); 069 070 ReentrantLock lock200 = locker.acquireLock("l2"); 071 Assert.assertNotEquals(lock2Hash, System.identityHashCode(lock200)); 072 lock200.unlock(); 073 Assert.assertFalse(lock200.isHeldByCurrentThread()); 074 075 // first lock is still there 076 Assert.assertTrue(lock1.isHeldByCurrentThread()); 077 lock1.unlock(); 078 Assert.assertFalse(lock1.isHeldByCurrentThread()); 079 } 080}