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: 480413 $ $Date: 2006-11-28 22:16:05 -0700 (Tue, 28 Nov 2006) $ 
27   */
28  public class PerformanceTest {
29      private int logLevel = 0;
30      private int nrIterations = 5;
31      private int nrThreads = 100;
32  
33      private GenericObjectPool pool;
34      private boolean start = false;
35      private volatile int waiting = 0;
36      private volatile int complete = 0;
37      private volatile long totalBorrowTime = 0;
38      private volatile long totalReturnTime = 0;
39      private volatile int nrSamples = 0; 
40  
41      public void setLogLevel(int i) {
42          logLevel = i;
43      }
44      
45      private void init() {
46          start = false;
47          waiting = 0;
48          complete = 0;
49          totalBorrowTime = 0;
50          totalReturnTime = 0;
51          nrSamples = 0;     
52      }
53  
54      class MyThread implements Runnable {
55          long borrowTime;
56          long returnTime;
57  
58          public void runOnce() {
59              try {
60                  waiting++;
61                  if (logLevel >= 5) {
62                      String name = "thread" + Thread.currentThread().getName();
63                      System.out.println(name + "   waiting: " + waiting + "   complete: " + complete);
64                  }
65                  long bbegin = System.currentTimeMillis();
66                  Object o = pool.borrowObject();
67                  long bend = System.currentTimeMillis();
68                  waiting--;
69                  do {
70                      Thread.yield();
71                  }
72                  while (!start);
73  
74                  if (logLevel >= 3) {
75                      String name = "thread" + Thread.currentThread().getName();
76                      System.out.println(name + "    waiting: " + waiting + "   complete: " + complete);
77                  }
78                                   
79                  long rbegin = System.currentTimeMillis();
80                  pool.returnObject(o);
81                  long rend = System.currentTimeMillis();
82                  Thread.yield();
83                  complete++;
84                  borrowTime = (bend-bbegin);
85                  returnTime = (rend-rbegin);
86              } catch (Exception e) {
87                  e.printStackTrace();
88              }
89          }
90  
91          public void run() {
92              runOnce(); // warmup
93              for (int i = 0; i<nrIterations; i++) {
94                  runOnce();
95                  totalBorrowTime += borrowTime;
96                  totalReturnTime += returnTime;
97                  nrSamples++;
98                  if (logLevel >= 2) {
99                      String name = "thread" + Thread.currentThread().getName();
100                     System.out.println(
101                         "result " + nrSamples + "\t" + name 
102                         + "\t" + "borrow time: " + borrowTime + "\t" + "return time: " + returnTime
103                         + "\t" + "waiting: " + waiting + "\t" + "complete: " + complete);
104                 }
105             }
106         }
107     }
108 
109     private void run(int nrIterations, int nrThreads, int maxActive, int maxIdle) {
110         this.nrIterations = nrIterations;
111         this.nrThreads = nrThreads;
112         init();
113         
114         SleepingObjectFactory factory = new SleepingObjectFactory();
115         if (logLevel >= 4) { factory.setDebug(true); } 
116         pool = new GenericObjectPool(factory);
117         pool.setMaxActive(maxActive);
118         pool.setMaxIdle(maxIdle);
119         pool.setTestOnBorrow(true);
120 
121         Thread[] threads = new Thread[nrThreads];
122         for (int i = 0; i < threads.length; i++) {
123             threads[i]= new Thread(new MyThread(), Integer.toString(i));
124             Thread.yield();
125         }
126         if (logLevel >= 1) { System.out.println("created"); } 
127         Thread.yield();
128 
129         for (int i = 0; i < threads.length; i++) {
130             threads[i].start();
131             Thread.yield();
132         }
133         if (logLevel >= 1) { System.out.println("started"); }
134         Thread.yield();
135 
136         start = true;
137         if (logLevel >= 1) { System.out.println("go"); }
138         Thread.yield();
139 
140         for (int i = 0; i < threads.length; i++) {
141             try {
142                 threads[i].join();
143             } catch (InterruptedException e) {
144                 e.printStackTrace();
145             }
146         }
147         if (logLevel >= 1) { System.out.println("finish"); }
148         System.out.println("-----------------------------------------");
149         System.out.println("nrIterations: " + nrIterations);
150         System.out.println("nrThreads: " + nrThreads);
151         System.out.println("maxActive: " + maxActive);
152         System.out.println("maxIdle: " + maxIdle);
153         System.out.println("nrSamples: " + nrSamples);
154         System.out.println("totalBorrowTime: " + totalBorrowTime);
155         System.out.println("totalReturnTime: " + totalReturnTime);
156         System.out.println("avg BorrowTime: " + totalBorrowTime/nrSamples);
157         System.out.println("avg ReturnTime: " + totalReturnTime/nrSamples);
158     }
159 
160     public static void main(String[] args) {
161         PerformanceTest test = new PerformanceTest();
162         test.setLogLevel(0);
163         System.out.println("Increase threads");
164         test.run(1,  50,  5,  5);
165         test.run(1, 100,  5,  5);
166         test.run(1, 200,  5,  5);
167         test.run(1, 400,  5,  5);
168 
169         System.out.println("Increase threads & poolsize");
170         test.run(1,  50,  5,  5);
171         test.run(1, 100, 10, 10);
172         test.run(1, 200, 20, 20);
173         test.run(1, 400, 40, 40);
174 
175         System.out.println("Increase maxIdle");
176         test.run(1, 400, 40,  5);
177         test.run(1, 400, 40, 40);
178 
179 
180 //      System.out.println("Show creation/destruction of objects");
181 //      test.setLogLevel(4);
182 //      test.run(1, 400, 40,  5);
183     }
184 
185 }