我正在尝试衡量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}
这意味着 400 个电话在 0 秒内返回?这是不可能的。
我只是想看看每个线程需要多少时间来插入记录,然后将这些数字存储在 a 中Map
并从主线程打印该映射。
我认为我假设它正在发生的问题是因为这里的线程安全,这就是resetlap
我猜它在做零时设置为 Map 的原因。
如果是,我该如何避免这个问题?并且还需要histogram map
从主线程传递到Task的构造函数?因为我需要在所有线程完成后打印该 Map 以查看那里的数字。
更新:-
如果我删除divide by 1000
将数字存储为毫秒的东西,那么我可以看到除zero
. 所以看起来不错。
但是我发现的另一件事是数字不一致,如果我总结每个线程的时间,我会得到一些数字。而且我还打印了整个程序完成的时间。所以我比较了这两个数字,它们相差很大