のパフォーマンスを測定しようとしていますDatabase Insert
。そのために、メソッドの前にカウンターをリセットし、メソッドが完了した後の時間を計算StopWatch
するクラスを作成しました。executeUpdate
executeUpdate
そして、各スレッドにかかる時間を確認しようとしているので、それらの数値をConcurrentHashMap
.
以下は私のメインクラスです-
public static void main(String[] args) {
final int noOfThreads = 4;
final int noOfTasks = 100;
final AtomicInteger id = new AtomicInteger(1);
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
for (int i = 0; i < noOfTasks * noOfThreads; i++) {
service.submit(new Task(id));
}
while (!service.isTerminated()) {
}
//printing the histogram
System.out.println(Task.histogram);
}
以下はRunnableを実装するクラスで、データベースへの挿入における各スレッドのパフォーマンスを測定しようとしています。つまり、各スレッドがデータベースに挿入するのにかかる時間です-
class Task implements Runnable {
private final AtomicInteger id;
private StopWatch totalExecTimer = new StopWatch(Task.class.getSimpleName() + ".totalExec");
public static ConcurrentHashMap<Long, AtomicLong> histogram = new ConcurrentHashMap<Long, AtomicLong>();
public Task(AtomicInteger id) {
this.id = id;
}
@Override
public void run() {
dbConnection = getDBConnection();
preparedStatement = dbConnection.prepareStatement(Constants.INSERT_ORACLE_SQL);
//other preparedStatement
totalExecTimer.resetLap();
preparedStatement.executeUpdate();
totalExecTimer.accumulateLap();
final AtomicLong before = histogram.putIfAbsent(totalExecTimer.getCumulativeTime() / 1000, new AtomicLong(1L));
if (before != null) {
before.incrementAndGet();
}
}
}
以下は、StopWatch class
/**
* A simple stop watch.
*/
protected static class StopWatch {
private final String name;
private long lapStart;
private long cumulativeTime;
public StopWatch(String _name) {
name = _name;
}
/**
* Resets lap start time.
*/
public void resetLap() {
lapStart = System.currentTimeMillis();
}
/**
* Accumulates the lap time and return the current lap time.
*
* @return the current lap time.
*/
public long accumulateLap() {
long lapTime = System.currentTimeMillis() - lapStart;
cumulativeTime += lapTime;
return lapTime;
}
/**
* Gets the current cumulative lap time.
*
* @return
*/
public long getCumulativeTime() {
return cumulativeTime;
}
public String getName() {
return name;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append("=");
sb.append((cumulativeTime / 1000));
sb.append("s");
return sb.toString();
}
}
上記のプログラムを実行すると、400 行が挿入されていることがわかります。そして、ヒストグラムを印刷しているとき、私はこのようにしか見えません-
{0=400}
これは、0 秒で 400 件のコールが戻ってきたことを意味しますか? それは確かに不可能です。
各スレッドがレコードを挿入し、それらの数値をに保存Map
してメインスレッドからそのマップを出力するのにかかる時間を確認しようとしています。
ここでのスレッドセーフのために発生していると想定している問題は、resetlap
ゼロを実行しているたびに Map に設定されていることが原因だと思います。
はいの場合、どうすればこの問題を回避できますか? またhistogram map
、メインスレッドからタスクのコンストラクターに渡す必要がありますか? すべてのスレッドが終了した後にそのマップを印刷して、そこにある数字を確認する必要があるためです。
更新:-divide by 1000
数値をミリ秒として保存するもの
を削除すると、 以外の数値を表示できzero
ます。それで良さそうです。
しかし、もう1つわかったことは、数値が一貫していないことです。各スレッドの時間を合計すると、その数値が得られます。また、プログラム全体が終了する時間を印刷しています。だから私はこれらの2つの数字を比較すると、大きな差があります