    1   /* FairGenericObjectPoolTest
    2   *
    3   * $Id: FairGenericObjectPoolTest.java 4672 2006-09-27 00:03:16Z paul_jack $
    4   *
    5   * Created on Apr 7, 2006
    6   *
    7   * Copyright (C) 2006 Internet Archive.
    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  //    public void testUnfair() throws InterruptedException {
    29  ////        System.out.println("unfair");
    30  //        GenericObjectPool pool = new GenericObjectPool();
    31  //
    32  //        Object[] borrowOrder = tryPool(pool);
    33  //
    34  //        Object[] sortedOrder = (Object[]) borrowOrder.clone();
    35  //        Arrays.sort(sortedOrder);
    36  //        assertFalse("unexpectedly fair", Arrays.equals(borrowOrder,sortedOrder));
    37  //    }
    38
    39      public void testFair() throws InterruptedException {
    40  //        System.out.println("fair");
    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             // only block first time through
    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 }