1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.pool.performance;
18  
19  import org.apache.commons.pool.impl.GenericObjectPool;
20  
21  /***
22   * Multi-thread performance test
23   * 
24   * @author Dirk Verbeeck
25   * @version $Revision: 155430 $ $Date: 2005-02-26 08:13:28 -0500 (Sat, 26 Feb 2005) $ 
26   */
27  public class PerformanceTest {
28      private int logLevel = 0;
29      private int nrIterations = 5;
30      private int nrThreads = 100;
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         this.nrThreads = nrThreads;
111         init();
112         
113         SleepingObjectFactory factory = new SleepingObjectFactory();
114         if (logLevel >= 4) { factory.setDebug(true); } 
115         pool = new GenericObjectPool(factory);
116         pool.setMaxActive(maxActive);
117         pool.setMaxIdle(maxIdle);
118         pool.setTestOnBorrow(true);
119 
120         Thread[] threads = new Thread[nrThreads];
121         for (int i = 0; i < threads.length; i++) {
122             threads[i]= new Thread(new MyThread(), Integer.toString(i));
123             Thread.yield();
124         }
125         if (logLevel >= 1) { System.out.println("created"); } 
126         Thread.yield();
127 
128         for (int i = 0; i < threads.length; i++) {
129             threads[i].start();
130             Thread.yield();
131         }
132         if (logLevel >= 1) { System.out.println("started"); }
133         Thread.yield();
134 
135         start = true;
136         if (logLevel >= 1) { System.out.println("go"); }
137         Thread.yield();
138 
139         for (int i = 0; i < threads.length; i++) {
140             try {
141                 threads[i].join();
142             } catch (InterruptedException e) {
143                 e.printStackTrace();
144             }
145         }
146         if (logLevel >= 1) { System.out.println("finish"); }
147         System.out.println("-----------------------------------------");
148         System.out.println("nrIterations: " + nrIterations);
149         System.out.println("nrThreads: " + nrThreads);
150         System.out.println("maxActive: " + maxActive);
151         System.out.println("maxIdle: " + maxIdle);
152         System.out.println("nrSamples: " + nrSamples);
153         System.out.println("totalBorrowTime: " + totalBorrowTime);
154         System.out.println("totalReturnTime: " + totalReturnTime);
155         System.out.println("avg BorrowTime: " + totalBorrowTime/nrSamples);
156         System.out.println("avg ReturnTime: " + totalReturnTime/nrSamples);
157     }
158 
159     public static void main(String[] args) {
160         PerformanceTest test = new PerformanceTest();
161         test.setLogLevel(0);
162         System.out.println("Increase threads");
163         test.run(1,  50,  5,  5);
164         test.run(1, 100,  5,  5);
165         test.run(1, 200,  5,  5);
166         test.run(1, 400,  5,  5);
167 
168         System.out.println("Increase threads & poolsize");
169         test.run(1,  50,  5,  5);
170         test.run(1, 100, 10, 10);
171         test.run(1, 200, 20, 20);
172         test.run(1, 400, 40, 40);
173 
174         System.out.println("Increase maxIdle");
175         test.run(1, 400, 40,  5);
176         test.run(1, 400, 40, 40);
177 
178 
179 //      System.out.println("Show creation/destruction of objects");
180 //      test.setLogLevel(4);
181 //      test.run(1, 400, 40,  5);
182     }
183 
184 }