Glassfish - JEE6 - Use of Interceptor to measure p

2019-05-24 18:57发布

问题:

For measuring execution time of methods, I've seen suggestions to use

public class PerformanceInterceptor {
   @AroundInvoke
   Object measureTime(InvocationContext ctx) throws Exception {
   long beforeTime = System.currentTimeMillis();
   Object obj = null;
   try {
      obj = ctx.proceed();
      return obj;
   }
   finally {
      time = System.currentTimeMillis() - beforeTime;
      // Log time
   }
}

Then put

@Interceptors(PerformanceInterceptor.class) 

before whatever method you want measured.

Anyway I tried this and it seems to work fine.

I also added a

public static long countCalls = 0;

to the PerformanceInterceptor class and a

countCalls++; 

to the measureTime() which also seems to work o.k.

With my newby hat on, I will ask if my use of the countCalls is o.k. i.e that Glassfish/JEE6 is o.k. with me using static variables in a Java class that is used as an Interceptor.... in particular with regard to thread safety. I know that normally you are supposed to synchronize setting of class variables in Java, but I don't know what the case is with JEE6/Glassfish. Any thoughts ?

回答1:

There is not any additional thread safety provided by container in this case. Each bean instance does have its own instance of interceptor. As a consequence multiple thread can access static countCalls same time.

That's why you have to guard both reads and writes to it as usual. Other possibility is to use AtomicLong:

private static final AtomicLong callCount = new AtomicLong();

private long getCallCount() {
   return callCount.get();
}

private void increaseCountCall() {
   callCount.getAndIncrement();
}

As expected, these solutions will work only as long as all of the instances are in same JVM, for cluster shared storage is needed.