Reputation: 55122
StopWatch sw = new StopWatch();
sw.start();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker = new SingleConnectionRunnable();
executor.execute(worker);
}
sw.stop();
System.out.println("total time"+sw.toString());
sw.reset();
sw.start();
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker2 = new PooledConnectionRunnable();
executor.execute(worker2);
}
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
while (!executor.isTerminated()) {
}
sw.stop();
System.out.println("total time"+sw.toString());
I am trying to run some perf tests on the code above. I am trying to use the same executor
on different Runnable
and measure the time. But it doesn't quite work. the first "total time" is not correct which is in milliseconds.
I want to print the elapsed time on the first loop then print the second loop. Not sure how I can wait executor to finish the first one then restart the executor.
What is the correct way to get this done?
Upvotes: 0
Views: 90
Reputation:
First, awaitTermination
will block until all tasks terminate. Is there any particular reason that you use a while loop check after waiting potentially 70 years?
Anyways, to answer your question, in order to wait for the first run to finish, you should use a CountDownLatch
to signal completion of each thread and await for them in the main thread until they finish. You can also use a CyclicBarrier
to await until all your threads are ready to go before starting timing, like so:
...
CountDownLatch latch = new CountDownLatch(MYTHREADS);
CyclicBarrier cb = new CyclicBarrier(MYTHREADS, new Runnable() {
@Override public void run() {
sw.start();
}
});
for (...) {
Runnable worker = ...
executor.execute(new Runnable() {
@Override public void run() {
try {
cb.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
worker.run();
latch.countDown();
}
});
}
latch.await();
sw.stop();
...
I moved the sw.start()
to the beginning of the for-loop to avoid measuring object allocation overhead to setup (probably won't be measured anyways since its in ms).
You can also reset the two concurrency classes to run an indefinite number of times.
Upvotes: 1
Reputation: 7583
What you are doing now is:
You are not waiting for them to finish like you do with the second loop.
This is what you can do to fix this.
Make a callback method in the SingleConnectionRunnable.
This method will be called at the last point of this runnable (when you terminate it) and caught by the class that starts the loop (which is not method in the question but that is fine).
In this callback method you keep track of how many times it is called.
When it is called MYTHREAD amount of times you print the stopwatch time.
Now you know how long it will take until all started threads are finished.
Upvotes: 0