クライアント側コードのパフォーマンスを測定しようとしています。つまり、クライアントコード内の他のクラスはほとんどなく、時間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);
}
}
このコードもスレッドセーフコードですか? 複数のスレッドからもアクセスされるためです。