0

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

4

2 回答 2

0

我不明白你得到奇怪的数字是什么意思。我的疯狂猜测是,这是因为来自不同线程的输出被穿插了。

解决它的一种方法是根本不打印histogramfrom 该run方法。它已经是一个实例变量(尽管目前不需要),因此您可以:

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

  2. 创建一个ThreadTask.report打印的方法histogram

  3. 在所有线程都完成后,依次ThreadTask.report调用每个线程。

于 2013-01-31T02:36:32.677 回答
0

我认为您多次计算同一时间。如果您的线程未在同步块中执行这部分代码:

long start_time = System.currentTimeMillis();

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

那么有可能发生这种情况:

  1. Thread1: 长 start_time ...
  2. 线程1:结果= ...
  3. Thread2: 长 start_time ...
  4. 线程2:结果= ...
  5. Thread2:长差...
  6. Thread1:长差...

因此,您的会计将无法正常工作。您可以使用同步块或查看 Java 的java.lang.management(例如ThreadMXBeanThreadInfo),以获得线程环境中的计时功能。

更新:

另请参阅此相关 SO 问题的答案,以获取有关该问题以及如何解决该问题的更多详细信息。

于 2013-11-05T22:32:00.513 回答