001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.pool.performance;
019
020 import org.apache.commons.pool.impl.GenericObjectPool;
021
022 /**
023 * Multi-thread performance test
024 *
025 * @author Dirk Verbeeck
026 * @version $Revision: 775703 $ $Date: 2009-05-17 12:39:51 -0400 (Sun, 17 May 2009) $
027 */
028 public class PerformanceTest {
029 private int logLevel = 0;
030 private int nrIterations = 5;
031
032 private GenericObjectPool pool;
033 private boolean start = false;
034 private volatile int waiting = 0;
035 private volatile int complete = 0;
036 private volatile long totalBorrowTime = 0;
037 private volatile long totalReturnTime = 0;
038 private volatile int nrSamples = 0;
039
040 public void setLogLevel(int i) {
041 logLevel = i;
042 }
043
044 private void init() {
045 start = false;
046 waiting = 0;
047 complete = 0;
048 totalBorrowTime = 0;
049 totalReturnTime = 0;
050 nrSamples = 0;
051 }
052
053 class MyThread implements Runnable {
054 long borrowTime;
055 long returnTime;
056
057 public void runOnce() {
058 try {
059 waiting++;
060 if (logLevel >= 5) {
061 String name = "thread" + Thread.currentThread().getName();
062 System.out.println(name + " waiting: " + waiting + " complete: " + complete);
063 }
064 long bbegin = System.currentTimeMillis();
065 Object o = pool.borrowObject();
066 long bend = System.currentTimeMillis();
067 waiting--;
068 do {
069 Thread.yield();
070 }
071 while (!start);
072
073 if (logLevel >= 3) {
074 String name = "thread" + Thread.currentThread().getName();
075 System.out.println(name + " waiting: " + waiting + " complete: " + complete);
076 }
077
078 long rbegin = System.currentTimeMillis();
079 pool.returnObject(o);
080 long rend = System.currentTimeMillis();
081 Thread.yield();
082 complete++;
083 borrowTime = (bend-bbegin);
084 returnTime = (rend-rbegin);
085 } catch (Exception e) {
086 e.printStackTrace();
087 }
088 }
089
090 public void run() {
091 runOnce(); // warmup
092 for (int i = 0; i<nrIterations; i++) {
093 runOnce();
094 totalBorrowTime += borrowTime;
095 totalReturnTime += returnTime;
096 nrSamples++;
097 if (logLevel >= 2) {
098 String name = "thread" + Thread.currentThread().getName();
099 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 }