1

クライアント側コードのパフォーマンスを測定しようとしています。つまり、クライアントコード内の他のクラスはほとんどなく、時間end to end client side codeがかかります。だから私はそれを中心にベンチマークを行いました。

以下は、私が現在使用している簡単なプログラムです。しかし、それには問題があります。

public class PerformanceTest {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newFixedThreadPool(5);

        try {
            for (int i = 0; i < 10 * 5; i++) {
                executor.submit(new ThreadTask(i));
            }

            executor.shutdown();
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
        } catch (InterruptedException e) {

        }
    }
}

以下は、実装するクラスですRunnable interface

class ThreadTask implements Runnable {
    private int id;
    public static ConcurrentHashMap<Long, AtomicLong> millisecondsMap = new ConcurrentHashMap<Long, AtomicLong>();


    public ThreadTask(int id) {
        this.id = id;
    }

    @Override
    public void run() {


        long start = System.nanoTime();

        attributes = beClient.getAttributes(columnsList);

        long end = System.nanoTime() - start;

        final AtomicLong before = millisecondsMap.putIfAbsent(end / 1000000L, new AtomicLong(1L));
        if (before != null) {
            before.incrementAndGet(); //this is a blocking call in IBM JVM
        }
    }
}

問題文:-

私はIBM JVM自分のマシンで実行しています。IBM JVM私は代わりに使用している会社で働いているSUN JVMので、JVM部分を変更することはできません。

IBM JVMincrementAndGet()メソッドでは、まず第一に、私にとって非常に奇妙でした

/**
 * Atomically increments by one the current value.
 *
 * @return the updated value
 */
public final synchronized long incrementAndGet() {                          //IBM-perf_AtomicLong
   ++value;                                                                 //IBM-perf_AtomicLong
   return value;                                                            //IBM-perf_AtomicLong
}

つまりsynchronized、各スレッドが互いに待機することを意味します。Lock free solutionそして今、各メソッドのパフォーマンスを測定するためにこれを探しています。

私は知っています、ここには小さな待ち時間があります。しかし、クライアント側のコード内で測定したいメソッドのパフォーマンスが何であれ、通常はそのメソッドのすぐ上に以下の行を置きます

long start = System.nanoTime();

そして、これらの2行は同じ方法の後にありますが、ConcurrentHashMap

long end = System.nanoTime() - start;

final AtomicLong before = millisecondsMap.putIfAbsent(end / 1000000L, new AtomicLong(1L));
        if (before != null) {
            before.incrementAndGet();// this is a blocking call in IBM JVM
        }

したがって5-8 different methods、クライアント側のコードの異なるクラスに上記の同じコードがある場合。次に、各スレッドが値をインクリメントするためにそこで待機するため、エンドツーエンドのパフォーマンス測定は正しくありません。それが、このためのロックフリーのソリューションを探している理由です。

これを行う簡単な方法はありますか?誰でもこれの例を提供できますか?

前もって感謝します。

更新されたコード:-

public static ConcurrentHashMap<Long, Long> millisecondsMap = new ConcurrentHashMap<Long, Long>();

@Override
public void run() {


    long start = System.nanoTime();

    beAttributes = client.getAttributes(columnsList);

    long end = System.nanoTime() - start;

    long key = end / 1000000L;
    boolean done = false;

    while(!done) {
        long oldValue = millisecondsMap.get(key);
        done = millisecondsMap.replace(key, oldValue, oldValue + 1);
    }

}

このコードもスレッドセーフコードですか? 複数のスレッドからもアクセスされるためです。

4

1 に答える 1