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