Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用多线程测试任务性能?_Java_Multithreading_Performance_Concurrency_Java.util.concurrent - Fatal编程技术网

Java 如何使用多线程测试任务性能?

Java 如何使用多线程测试任务性能?,java,multithreading,performance,concurrency,java.util.concurrent,Java,Multithreading,Performance,Concurrency,Java.util.concurrent,我有一些练习,其中一个涉及并发性。这个主题对我来说是新的,但是我花了6个小时终于解决了我的问题。但我对相应的API的了解很差,所以我需要建议:我的解决方案是正确的还是有更合适的方法 因此,我必须实现下一个接口: public interface PerformanceTester { /** * Runs a performance test of the given task. * @param task which task to do performan

我有一些练习,其中一个涉及并发性。这个主题对我来说是新的,但是我花了6个小时终于解决了我的问题。但我对相应的API的了解很差,所以我需要建议:我的解决方案是正确的还是有更合适的方法

因此,我必须实现下一个接口:

public interface PerformanceTester {    
    /**
     * Runs a performance test of the given task.
     * @param task which task to do performance tests on
     * @param executionCount how many times the task should be executed in total
     * @param threadPoolSize how many threads to use
     */
    public PerformanceTestResult runPerformanceTest(
            Runnable task,
            int executionCount, 
            int threadPoolSize) throws InterruptedException;
}
其中PerformanceTestResult包含总时间(整个性能测试的总时间)、最短时间(最短单次执行的时间)和最长时间(最长单次执行的时间)

所以,今天我学到了很多新东西-关于线程池、类型
执行器
执行服务
未来
完成服务
等等

如果我有
可调用任务
,我可以执行下一步:

  • call()过程的末尾返回当前时间
  • 创建一些数据结构(一些映射可能是)来存储开始时间和
    Future
    对象,这些对象由
    fixedThreadPool.submit(task)
    返回(在循环中执行此操作
    executionCount
    次)
  • 执行后,我可以从每个
    将来的
    结束时间中减去开始时间
  • (在可调用任务的情况下,这种方法正确吗?)

    但是!我只有
    可运行任务
    ,所以我继续寻找。我甚至创建了
    FutureListener实现可调用的
    ,当
    Future.isDone()
    时,它必须返回时间,但对我来说有点疯狂(我必须加倍线程计数)

    因此,最终我注意到
    CompletionService
    使用有趣的方法
    take()
    键入,该方法检索并删除表示下一个已完成任务的未来,如果还没有,则等待,这是一个很好的使用示例。这就是我的解决方案

    public class PerformanceTesterImpl implements PerformanceTester {
    
    
    @Override
    public PerformanceTestResult runPerformanceTest(Runnable task,
            int executionCount, int threadPoolSize) throws InterruptedException {
        long totalTime = 0;
        long[] times = new long[executionCount];
    
        ExecutorService pool = Executors.newFixedThreadPool(threadPoolSize);
    
        //create list of executionCount tasks 
        ArrayList<Runnable> solvers = new ArrayList<Runnable>();
        for (int i = 0; i < executionCount; i++) {
            solvers.add(task);
        }
    
        CompletionService<Long> ecs = new ExecutorCompletionService<Long>(pool);
    
        //submit tasks and save time of execution start
        for (Runnable s : solvers)
            ecs.submit(s, System.currentTimeMillis());
    
        //take Futures one by one in order of completing
        for (int i = 0; i < executionCount; ++i) {
            long r = 0;
            try {
                //this is saved time of execution start
                r = ecs.take().get();
            } catch (ExecutionException e) {
                e.printStackTrace();
                return null;
            }
            //put into array difference between current time and start time
            times[i] = System.currentTimeMillis() - r;
            //calculate sum in array
            totalTime += times[i];
        }
    
        pool.shutdown();
        //sort array to define min and max
        Arrays.sort(times);        
    
        PerformanceTestResult performanceTestResult = new PerformanceTestResult(
                totalTime, times[0], times[executionCount - 1]);
        return performanceTestResult;
    }
    }
    
    公共类PerformanceTesterImpl实现PerformanceTester{
    @凌驾
    公共性能测试结果runPerformanceTest(可运行任务,
    int executionCount,int threadPoolSize)引发InterruptedException{
    长总时间=0;
    long[]次=新的long[executionCount];
    ExecutorService池=Executors.newFixedThreadPool(threadPoolSize);
    //创建executionCount任务列表
    ArrayList解算器=新的ArrayList();
    for(int i=0;i

    那么,你能说什么?感谢您的回复。

    我会使用System.nanoTime()进行更高分辨率的计时。您可能希望忽略前10000个测试,以确保JVM已经预热

    我不会费心创建一个Runnable列表并将其添加到Executor。相反,我会将它们添加到遗嘱执行人中

    使用Runnable并不是问题,因为您得到了一个
    Future

    注意:计时任务在队列中花费的时间会对计时产生很大影响。不必从创建任务时开始计算时间,您可以将任务时间本身计算在内,并以纳秒为单位返回Long。时间安排的方式应该反映您心目中的用例


    一种将可运行任务转换为自身计时任务的简单方法

    finla Runnable run = ...
    ecs.submit(new Callable<Long>() {
        public Long call() {
             long start = System.nanoTime();
             run.run();
             return System.nanoTime() - start;
        }
    });
    
    finla可运行运行=。。。
    ecs.submit(新的可调用(){
    公共长途电话(){
    长启动=System.nanoTime();
    run.run();
    返回系统.nanoTime()-开始;
    }
    });
    
    我会使用System.nanoTime()进行更高分辨率的计时。您可能希望忽略前10000个测试,以确保JVM已经预热

    我不会费心创建一个Runnable列表并将其添加到Executor。相反,我会将它们添加到遗嘱执行人中

    使用Runnable并不是问题,因为您得到了一个
    Future

    注意:计时任务在队列中花费的时间会对计时产生很大影响。不必从创建任务时开始计算时间,您可以将任务时间本身计算在内,并以纳秒为单位返回Long。时间安排的方式应该反映您心目中的用例


    一种将可运行任务转换为自身计时任务的简单方法

    finla Runnable run = ...
    ecs.submit(new Callable<Long>() {
        public Long call() {
             long start = System.nanoTime();
             run.run();
             return System.nanoTime() - start;
        }
    });
    
    finla可运行运行=。。。
    ecs.submit(新的可调用(){
    公共长途电话(){
    长启动=System.nanoTime();
    run.run();
    返回系统.nanoTime()-开始;
    }
    });
    
    在JVM中编写性能测试时有许多复杂的问题。您可能不担心他们,因为这是一个练习,但如果您担心,这个问题可能会有更多信息:

    也就是说,您的代码中似乎没有任何明显的bug。如果您希望对代码进行全面审查,您可能需要在较低的交通代码审查网站上询问此问题:

    在JVM中编写性能测试时有许多复杂的问题。您可能不担心他们,因为这是一个练习,但如果您担心,这个问题可能会有更多信息:

    也就是说,似乎没有任何明显的bug