I have a object call Counter which basically looks like this:
private long count;
private long errors;
private long duration;
private long errorDuration;
With two "time" methods for timing methods that return something and other methods which are void.
public <T> T time(ReturningRunnable<T> runnable) {
long start = currentTimeMillis();
T result = null;
try {
result = runnable.run();
} catch (Throwable ex) {
errorDuration += currentTimeMillis() - start;
errors++;
throw runtime(ex);
}
duration += currentTimeMillis() - start;
count++;
return result;
}
public void time(Runnable runnable) {
time(new RunnableRunner(runnable));
}
I chose to rethrow the exceptions as runtime exceptions (as i'm not a fan of checked exceptions) but you could just as well make your custom MyRunnable interface throw exceptions and just catch and re-throw them. Here's a usage of the above:
counter.time(new Runnable() {
@Override
public void run() {
// Do something
});
Or this, in the returning-value case:
return counter.time(new ReturningRunnable<Integer>() {
@Override
public Integer run() {
return 1; // You get the idea
});
I like this because my counter objects can be exposed over JMX and injected wherever i need them. You could do what you've asked with reflection, but i think that would be messy (IMHO).