View Javadoc

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
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
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
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)
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 }