1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.pool.performance;
19  
20  import org.apache.commons.pool.impl.GenericObjectPool;
21  
22  /**
23   * Multi-thread performance test
24   * 
25   * @author Dirk Verbeeck
26   * @version $Revision: 775703 $ $Date: 2009-05-17 12:39:51 -0400 (Sun, 17 May 2009) $ 
27   */
28  public class PerformanceTest {
29      private int logLevel = 0;
30      private int nrIterations = 5;
31  
32      private GenericObjectPool pool;
33      private boolean start = false;
34      private volatile int waiting = 0;
35      private volatile int complete = 0;
36      private volatile long totalBorrowTime = 0;
37      private volatile long totalReturnTime = 0;
38      private volatile int nrSamples = 0; 
39  
40      public void setLogLevel(int i) {
41          logLevel = i;
42      }
43      
44      private void init() {
45          start = false;
46          waiting = 0;
47          complete = 0;
48          totalBorrowTime = 0;
49          totalReturnTime = 0;
50          nrSamples = 0;     
51      }
52  
53      class MyThread implements Runnable {
54          long borrowTime;
55          long returnTime;
56  
57          public void runOnce() {
58              try {
59                  waiting++;
60                  if (logLevel >= 5) {
61                      String name = "thread" + Thread.currentThread().getName();
62                      System.out.println(name + "   waiting: " + waiting + "   complete: " + complete);
63                  }
64                  long bbegin = System.currentTimeMillis();
65                  Object o = pool.borrowObject();
66                  long bend = System.currentTimeMillis();
67                  waiting--;
68                  do {
69                      Thread.yield();
70                  }
71                  while (!start);
72  
73                  if (logLevel >= 3) {
74                      String name = "thread" + Thread.currentThread().getName();
75                      System.out.println(name + "    waiting: " + waiting + "   complete: " + complete);
76                  }
77                                   
78                  long rbegin = System.currentTimeMillis();
79                  pool.returnObject(o);
80                  long rend = System.currentTimeMillis();
81                  Thread.yield();
82                  complete++;
83                  borrowTime = (bend-bbegin);
84                  returnTime = (rend-rbegin);
85              } catch (Exception e) {
86                  e.printStackTrace();
87              }
88          }
89  
90          public void run() {
91              runOnce(); // warmup
92              for (int i = 0; i<nrIterations; i++) {
93                  runOnce();
94                  totalBorrowTime += borrowTime;
95                  totalReturnTime += returnTime;
96                  nrSamples++;
97                  if (logLevel >= 2) {
98                      String name = "thread" + Thread.currentThread().getName();
99                      System.out.println(
100                         "result " + nrSamples + "\t" + name 
101                         + "\t" + "borrow time: " + borrowTime + "\t" + "return time: " + returnTime
102                         + "\t" + "waiting: " + waiting + "\t" + "complete: " + complete);
103                 }
104             }
105         }
106     }
107 
108     private void run(int nrIterations, int nrThreads, int maxActive, int maxIdle) {
109         this.nrIterations = nrIterations;
110         init();
111         
112         SleepingObjectFactory factory = new SleepingObjectFactory();
113         if (logLevel >= 4) { factory.setDebug(true); } 
114         pool = new GenericObjectPool(factory);
115         pool.setMaxActive(maxActive);
116         pool.setMaxIdle(maxIdle);
117         pool.setTestOnBorrow(true);
118 
119         Thread[] threads = new Thread[nrThreads];
120         for (int i = 0; i < threads.length; i++) {
121             threads[i]= new Thread(new MyThread(), Integer.toString(i));
122             Thread.yield();
123         }
124         if (logLevel >= 1) { System.out.println("created"); } 
125         Thread.yield();
126 
127         for (int i = 0; i < threads.length; i++) {
128             threads[i].start();
129             Thread.yield();
130         }
131         if (logLevel >= 1) { System.out.println("started"); }
132         Thread.yield();
133 
134         start = true;
135         if (logLevel >= 1) { System.out.println("go"); }
136         Thread.yield();
137 
138         for (int i = 0; i < threads.length; i++) {
139             try {
140                 threads[i].join();
141             } catch (InterruptedException e) {
142                 e.printStackTrace();
143             }
144         }
145         if (logLevel >= 1) { System.out.println("finish"); }
146         System.out.println("-----------------------------------------");
147         System.out.println("nrIterations: " + nrIterations);
148         System.out.println("nrThreads: " + nrThreads);
149         System.out.println("maxActive: " + maxActive);
150         System.out.println("maxIdle: " + maxIdle);
151         System.out.println("nrSamples: " + nrSamples);
152         System.out.println("totalBorrowTime: " + totalBorrowTime);
153         System.out.println("totalReturnTime: " + totalReturnTime);
154         System.out.println("avg BorrowTime: " + totalBorrowTime/nrSamples);
155         System.out.println("avg ReturnTime: " + totalReturnTime/nrSamples);
156     }
157 
158     public static void main(String[] args) {
159         PerformanceTest test = new PerformanceTest();
160         test.setLogLevel(0);
161         System.out.println("Increase threads");
162         test.run(1,  50,  5,  5);
163         test.run(1, 100,  5,  5);
164         test.run(1, 200,  5,  5);
165         test.run(1, 400,  5,  5);
166 
167         System.out.println("Increase threads & poolsize");
168         test.run(1,  50,  5,  5);
169         test.run(1, 100, 10, 10);
170         test.run(1, 200, 20, 20);
171         test.run(1, 400, 40, 40);
172 
173         System.out.println("Increase maxIdle");
174         test.run(1, 400, 40,  5);
175         test.run(1, 400, 40, 40);
176 
177 
178 //      System.out.println("Show creation/destruction of objects");
179 //      test.setLogLevel(4);
180 //      test.run(1, 400, 40,  5);
181     }
182 
183 }