我正在衡量我们服务的表现。所以我有一个URL来调用我们的服务。所以我做的是在拨打服务之前,我记下时间,在响应从服务回来之后,我测量响应时间。我编写了一个程序来调用我的服务并通过将数字放在HashMap中来衡量性能 -
while (runs > 0) {
long start_time = System.currentTimeMillis();
result = restTemplate.getForObject("Some URL", String.class);
long difference = (System.currentTimeMillis() - start_time);
Long count = histogram.get(difference);
if (count != null) {
count++;
histogram.put(Long.valueOf(difference), count);
} else {
histogram.put(Long.valueOf(difference), Long.valueOf(1L));
}
runs--;
}
因此,我将从直方图中获得的输出为 - X number of calls came back in Y ms
现在我在想的是,而不是一次拨打一个电话,为什么我不应该对我们服务的调用进行并行化,就像我以前的程序一样,我一个接一个地点击服务。所以我写了一篇 下面的多线程程序将同时调用我的服务。那么下面的程序能否准确测量时差?
就像一个线程花了这么多时间,第二个线程需要花费这么多时间,第三个线程需要花费这么多时间等等?是否可以这样做?
如果是的话,如果我的以下程序效果不好,有人可以告诉我该怎么做吗?
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1 * 2; i++) {
service.submit(new ThreadTask(i));
}
service.shutdown();
try {
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
}
}
class ThreadTask implements Runnable {
private int id;
private RestTemplate restTemplate = new RestTemplate();
private String result;
private HashMap<Long, Long> histogram;
public ThreadTask(int id) {
this.id = id;
}
@Override
public void run() {
long start_time = System.currentTimeMillis();
result = restTemplate.getForObject("Some URL",String.class);
long difference = (System.currentTimeMillis() - start_time);
Long count = histogram.get(difference);
if (count != null) {
count++;
histogram.put(Long.valueOf(difference), count);
} else {
histogram.put(Long.valueOf(difference), Long.valueOf(1L));
}
System.out.println(histogram);
}
}
因为每当我运行程序时,我从这个多线程程序中得到的数字看起来都很奇怪。
我从非多线程程序获得的输出
168=1
41=1
43=3
1 call came back in 168 ms
等等......
我从多线程程序获得的输出
{119=1}
{179=1}
{150=1}
{202=1}
{149=1}
1 call came back in 119 ms
等等......
那么在多线程程序中,我猜它需要花费更多的时间吗?
答案 0 :(得分:0)
我不明白你的意思是得到奇怪的数字。我的猜测是因为不同线程的输出正在散布。
解决此问题的一种方法是根本不打印histogram
方法中的run
。它已经是一个实例变量(虽然它目前不需要),所以你可以:
而不是提交ThreadTask
未命名的实例将它们存储在列表/数组中。
创建一个打印ThreadTask.report
histogram
完成所有线程后,按顺序在每个上调用ThreadTask.report
。
答案 1 :(得分:0)
我认为你是多次同时考虑的。如果你的线程没有在同步块中执行这部分代码:
long start_time = System.currentTimeMillis();
result = restTemplate.getForObject("Some URL",String.class);
long difference = (System.currentTimeMillis() - start_time);
然后有可能发生这种情况:
因此,您的会计将无法正常运作。您可以使用synchronized块或查看Java的java.lang.management
(例如,ThreadMXBean
和ThreadInfo
),以获取线程环境中的计时功能。
<强>更新强>
另请参阅this related SO question for more details关于问题的答案以及如何解决问题。