1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.hbase.util; 20 21 import java.util.concurrent.CountDownLatch; 22 import java.util.concurrent.atomic.AtomicBoolean; 23 import java.util.concurrent.atomic.AtomicReference; 24 25 import org.apache.hadoop.hbase.testclassification.SmallTests; 26 import org.junit.Assert; 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.experimental.categories.Category; 30 31 @Category({SmallTests.class}) 32 public class TestWeakObjectPool { 33 WeakObjectPool<String, Object> pool; 34 35 @Before setUp()36 public void setUp() { 37 pool = new WeakObjectPool<String, Object>( 38 new WeakObjectPool.ObjectFactory<String, Object>() { 39 @Override 40 public Object createObject(String key) { 41 return new Object(); 42 } 43 }); 44 } 45 46 @Test testKeys()47 public void testKeys() { 48 Object obj1 = pool.get("a"); 49 Object obj2 = pool.get(new String("a")); 50 51 Assert.assertSame(obj1, obj2); 52 53 Object obj3 = pool.get("b"); 54 55 Assert.assertNotSame(obj1, obj3); 56 } 57 58 @Test testWeakReference()59 public void testWeakReference() throws Exception { 60 Object obj1 = pool.get("a"); 61 int hash1 = System.identityHashCode(obj1); 62 63 System.gc(); 64 System.gc(); 65 System.gc(); 66 67 Thread.sleep(10); 68 // Sleep a while because references newly becoming stale 69 // may still remain when calling the {@code purge} method. 70 pool.purge(); 71 Assert.assertEquals(1, pool.size()); 72 73 Object obj2 = pool.get("a"); 74 Assert.assertSame(obj1, obj2); 75 76 obj1 = null; 77 obj2 = null; 78 79 System.gc(); 80 System.gc(); 81 System.gc(); 82 83 Thread.sleep(10); 84 pool.purge(); 85 Assert.assertEquals(0, pool.size()); 86 87 Object obj3 = pool.get("a"); 88 Assert.assertNotEquals(hash1, System.identityHashCode(obj3)); 89 } 90 91 @Test(timeout=1000) testCongestion()92 public void testCongestion() throws Exception { 93 final int THREAD_COUNT = 100; 94 95 final AtomicBoolean assertionFailed = new AtomicBoolean(); 96 final AtomicReference<Object> expectedObjRef = new AtomicReference<Object>(); 97 final CountDownLatch prepareLatch = new CountDownLatch(THREAD_COUNT); 98 final CountDownLatch startLatch = new CountDownLatch(1); 99 final CountDownLatch endLatch = new CountDownLatch(THREAD_COUNT); 100 101 for (int i=0; i<THREAD_COUNT; i++) { 102 new Thread() { 103 @Override 104 public void run() { 105 prepareLatch.countDown(); 106 try { 107 startLatch.await(); 108 109 Object obj = pool.get("a"); 110 if (! expectedObjRef.compareAndSet(null, obj)) { 111 if (expectedObjRef.get() != obj) { 112 assertionFailed.set(true); 113 } 114 } 115 } catch (Exception e) { 116 assertionFailed.set(true); 117 118 } finally { 119 endLatch.countDown(); 120 } 121 } 122 }.start(); 123 } 124 125 prepareLatch.await(); 126 startLatch.countDown(); 127 endLatch.await(); 128 129 if (assertionFailed.get()) { 130 Assert.fail(); 131 } 132 } 133 } 134