1
2
3
4
5
6
7
8
9
10 package org.apache.commons.pool.impl;
11
12 import java.util.Arrays;
13 import java.util.Collections;
14 import java.util.LinkedList;
15 import java.util.List;
16
17 import junit.framework.TestCase;
18
19 import org.apache.commons.pool.BasePoolableObjectFactory;
20
21 /***
22 * Test for FairGenericObjectPool.
23 *
24 * @author gojomo
25 */
26 @SuppressWarnings("unchecked")
27 public class FairGenericObjectPoolTest extends TestCase {
28
29
30
31
32
33
34
35
36
37
38
39 public void testFair() throws InterruptedException {
40
41 GenericObjectPool pool = new FairGenericObjectPool();
42
43 Object[] borrowOrder = tryPool(pool);
44
45 Object[] sortedOrder = (Object[]) borrowOrder.clone();
46 Arrays.sort(sortedOrder);
47 assertTrue("unexpectedly unfair", Arrays.equals(borrowOrder,sortedOrder));
48 }
49
50 /***
51 * Test the given pool for fairness.
52 *
53 * @param pool GenericObjectPool to test
54 * @throws InterruptedException
55 */
56 private Object[] tryPool(GenericObjectPool pool) throws InterruptedException {
57 BlockerObjectFactory factory = new BlockerObjectFactory();
58 pool.setFactory(factory);
59 pool.setMaxActive(1);
60 List borrowOrder = Collections.synchronizedList(new LinkedList());
61 for(int i = 0; i < 10; i++) {
62 Contender c = new Contender(borrowOrder);
63 c.pool = pool;
64 c.ordinal = i;
65 (new Thread(c)).start();
66 Thread.sleep(500);
67 }
68 factory.single.release();
69 Thread.sleep(5000);
70 return borrowOrder.toArray();
71 }
72
73 class Contender implements Runnable {
74 public GenericObjectPool pool;
75 public int ordinal;
76 public List reportList;
77
78 public Contender(List borrowOrder) {
79 reportList = borrowOrder;
80 }
81
82 public void run() {
83 try {
84 Blocker block = (Blocker) pool.borrowObject();
85 System.out.println("borrowed #"+ordinal);
86 reportList.add(new Integer(ordinal));
87 block.acquire();
88 System.out.println("returning #"+ordinal);
89 pool.returnObject(block);
90 } catch (Exception e) {
91 throw new RuntimeException(e);
92 }
93 }
94
95 }
96
97 class BlockerObjectFactory extends BasePoolableObjectFactory {
98 public Blocker single = new Blocker();
99 public Object makeObject() throws Exception {
100 System.out.println("makeObject");
101 return single;
102 }
103 }
104
105 class Blocker {
106 boolean block = true;
107 public synchronized void acquire() {
108
109 if(block) {
110 try {
111 wait();
112 } catch (InterruptedException e) {
113 throw new RuntimeException(e);
114 }
115 }
116 block = false;
117 }
118 public synchronized void release() {
119 notifyAll();
120 }
121 }
122 }