2

メソッドの実行時間を測定するために、使用する提案を見てきました

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
   }
}

次に入れます

@Interceptors(PerformanceInterceptor.class) 

測定したい方法の前に。

とにかく私はこれを試しました、そしてそれはうまくいくようです。

私も追加しました

public static long countCalls = 0;

PerformanceInterceptorクラスと

countCalls++; 

これも問題なく機能しているように見えるmeasureTime()に

newbyの帽子をかぶった状態で、countCallsの使用が、Glassfish / JEE6がインターセプターとして使用されるJavaクラスの静的変数を使用しても問題ないかどうかを尋ねます。特に、スレッドセーフに関してです。通常、Javaでクラス変数の設定を同期することになっていることは知っていますが、JEE6/Glassfishの場合はどうなるかわかりません。何かご意見は ?

4

1 に答える 1

1

この場合、コンテナによって提供される追加のスレッドセーフはありません。各Beanインスタンスには、独自のインターセプターのインスタンスがあります。結果として、複数のスレッドが静的なcountCallsに同時にアクセスできます。

そのため、通常どおり、読み取りと書き込みの両方を保護する必要があります。他の可能性はAtomicLongを使用することです:

private static final AtomicLong callCount = new AtomicLong();

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

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

予想どおり、これらのソリューションは、すべてのインスタンスが同じJVMにある場合にのみ機能します。これは、クラスター共有ストレージが必要なためです。

于 2012-07-19T08:44:23.707 に答える