Java 计算多线程代码中的吞吐量

Java 计算多线程代码中的吞吐量,java,multithreading,throughput,Java,Multithreading,Throughput,我正在对我的一些客户代码进行基准测试。现在,我正试图找出如何通过我的多线程代码计算吞吐量- 我用20个线程运行我的程序。每个线程将运行15分钟,因此所有20个线程将运行15分钟 下面是我的代码- public static void main(String[] args) { try { // create thread pool with given size ExecutorService service = Executors.newFixedThrea

我正在对我的一些客户代码进行基准测试。现在,我正试图找出如何通过我的
多线程
代码计算吞吐量-

我用
20个线程运行我的程序。每个线程将运行
15分钟
,因此所有
20个线程将运行15分钟

下面是我的代码-

public static void main(String[] args) {

try {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(20);

        // queue some tasks
        long startTime = System.currentTimeMillis();
        long endTime = startTime + (15 * 60 * 1000);

        for (int i = 0; i < 20; i++) {
            service.submit(new CassandraReadTask(endTime, columnFamilyList));
        }

        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    } catch (Exception e) {
        LOG.warn("Threw a Exception in" + CNAME + e);
    }
}
从上面的代码中,我生成了一些随机id,我用它来传递给我的
getAttributes
dao方法

据我了解。总吞吐量将为-

total number of request/ total duration the program was run
因此,在我的情况下,它将是-

total number of id's I have generated/15 minutes

我说得对吗?

这似乎是对的,但你怎么计算呢?您可以使用Callables而不是Runnable来返回生成的ID的数量。然后,在关闭执行器之后,您将获得所有的未来,并对其进行汇总。

只要您正确地计算(可能使用共享的
原子整数
?)不同线程完成的所有请求,您正在做的事情就可以了

不过,我会稍微改变一下您的代码,提交100000个(或更多)随机ID,然后计算线程处理所有这些ID所需的时间。这是一个更现实的测试,因为它将更好地显示您的任务提交开销

然后你只需要把一个
startTimeMillis
和计算从结束到开始的差异,然后计算100000(或任何你的数字)除以差异,得到你的平均迭代/毫秒

比如:

long startTimeMillis = System.currentTimeMillis();
int numIterations = 100000;
for (int i = 0; i < numIterations; i++) {
    double randomNumber = random.nextDouble() * 100.0;
    final String id = generateRandomId(random);
    service.submit(new CassandraReadTask(id, columnFamilyList));
}
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
long diff = System.currentTimeMillis() - startTimeMillis;
System.out.println("Average time per iteration is " + (numIterations / diff));
long startTimeMillis=System.currentTimeMillis();
整数=100000;
对于(int i=0;i

然后就可以轻松地处理线程数和迭代次数,以最大限度地提高吞吐量。

我生成的id是
字符串id
,因此它看起来像,
1
100
2000
。所以每次它生成任何东西时,我都将静态计数器增加
1
。在上面的示例中,我没有显示计数器的代码。但我就是这样做的。然后我可以用这个计数器来计算吞吐量。这听起来对吗?好吧,如果你有一些地方可以计算,那么你就不需要使用期货。但该计数器必须是线程安全的,这意味着另一个同步点,因此吞吐量比不进行计数时要低。最好使用Gray的方法,提交已知数量的作业并计算它们的执行时间。你能提供一个完整的工作示例吗?它只测量创建任务的时间,而不是实际运行任务,对吗?是的,我也是这么想的。如果我错了,请纠正我,格雷。正确的。我忘了复制
shutdown()
等待终止(…)
。谢谢@RalfH。是的,我正在使用
AtomicInteger
来计算它。
long startTimeMillis = System.currentTimeMillis();
int numIterations = 100000;
for (int i = 0; i < numIterations; i++) {
    double randomNumber = random.nextDouble() * 100.0;
    final String id = generateRandomId(random);
    service.submit(new CassandraReadTask(id, columnFamilyList));
}
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
long diff = System.currentTimeMillis() - startTimeMillis;
System.out.println("Average time per iteration is " + (numIterations / diff));