用于衡量服务性能的多线程程序

时间:2013-01-31 02:25:02

标签: java multithreading

我正在衡量我们服务的表现。所以我有一个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等等......  那么在多线程程序中,我猜它需要花费更多的时间吗?

2 个答案:

答案 0 :(得分:0)

我不明白你的意思是得到奇怪的数字。我的猜测是因为不同线程的输出正在散布。

解决此问题的一种方法是根本不打印histogram方法中的run。它已经是一个实例变量(虽然它目前不需要),所以你可以:

  1. 而不是提交ThreadTask未命名的实例将它们存储在列表/数组中。

  2. 创建一个打印ThreadTask.report

  3. 的方法histogram
  4. 完成所有线程后,按顺序在每个上调用ThreadTask.report

答案 1 :(得分:0)

我认为你是多次同时考虑的。如果你的线程没有在同步块中执行这部分代码:

long start_time = System.currentTimeMillis();

result = restTemplate.getForObject("Some URL",String.class);
long difference = (System.currentTimeMillis() - start_time);

然后有可能发生这种情况:

  1. Thread1:long start_time ...
  2. Thread1:result = ...
  3. Thread2:long start_time ...
  4. Thread2:result = ...
  5. 线程2:差异很大......
  6. 线程1:差异很大......
  7. 因此,您的会计将无法正常运作。您可以使用synchronized块或查看Java的java.lang.management(例如,ThreadMXBeanThreadInfo),以获取线程环境中的计时功能。

    <强>更新

    另请参阅this related SO question for more details关于问题的答案以及如何解决问题。