Как вычислить общее время выполнения в многопоточном приложении - PullRequest
0 голосов
/ 06 мая 2020

Есть приложение, которое мне нужно протестировать, чтобы увидеть взаимосвязь между количеством потоков и общей продолжительностью выполнения в многопоточном приложении. Это то, что я пытаюсь сейчас сделать:

    //Start time of thread executions.
    long start = System.currentTimeMillis();
    //Here, I am initializing the thread list which will store each thread.
    MyThreadClass[] threads = new MyThreadClass[numOfThreads];
    //Start each thread.
    for (int i = 0; i < threads.length; i++) {
        threads[i] = new MyThreadClass(/*Constructor parameters here*/);
        //Start the thread.
        threads[i].start();
        //There is a variable assignment to change the parameter of a constructor on next iteration.
    }
    //Join all the threads.
    for (MyThreadClass thread : threads) {
        thread.join();
    }

    //After all threads are done, compute the elapsed time to get computation time.
    long finish = System.currentTimeMillis();
    long duration = finish - start;
    System.out.println("Total duration of the computation with " + threads.length + " thread is " + duration + " milliseconds.");

Но вот проблема, когда я тестировал приложение, заключив код в main() с некоторыми для l oop для тестирования. Я считаю, что с этим числом что-то неразумно.

Total duration of the computation with 1 thread is 50 milliseconds.
Total duration of the computation with 2 thread is 25 milliseconds.
Total duration of the computation with 3 thread is 25 milliseconds.
Total duration of the computation with 4 thread is 15 milliseconds.
Total duration of the computation with 5 thread is 19 milliseconds.
Total duration of the computation with 6 thread is 16 milliseconds.
Total duration of the computation with 7 thread is 15 milliseconds.
Total duration of the computation with 8 thread is 25 milliseconds.
Total duration of the computation with 9 thread is 20 milliseconds.
Total duration of the computation with 10 thread is 20 milliseconds.
Total duration of the computation with 11 thread is 30 milliseconds.
Total duration of the computation with 12 thread is 34 milliseconds.
Total duration of the computation with 13 thread is 34 milliseconds.
Total duration of the computation with 14 thread is 18 milliseconds.
Total duration of the computation with 15 thread is 18 milliseconds.
Total duration of the computation with 16 thread is 18 milliseconds.
Total duration of the computation with 17 thread is 15 milliseconds.
Total duration of the computation with 18 thread is 19 milliseconds.
Total duration of the computation with 19 thread is 17 milliseconds.
Total duration of the computation with 20 thread is 13 milliseconds.
Total duration of the computation with 21 thread is 13 milliseconds.
Total duration of the computation with 22 thread is 13 milliseconds.
Total duration of the computation with 23 thread is 12 milliseconds.
Total duration of the computation with 24 thread is 12 milliseconds.
Total duration of the computation with 25 thread is 14 milliseconds.
Total duration of the computation with 26 thread is 15 milliseconds.
Total duration of the computation with 27 thread is 18 milliseconds.
Total duration of the computation with 28 thread is 20 milliseconds.
Total duration of the computation with 29 thread is 20 milliseconds.
Total duration of the computation with 30 thread is 15 milliseconds.
Total duration of the computation with 31 thread is 22 milliseconds.
Total duration of the computation with 32 thread is 23 milliseconds.
Total duration of the computation with 33 thread is 17 milliseconds.
Total duration of the computation with 34 thread is 33 milliseconds.
Total duration of the computation with 35 thread is 20 milliseconds.
Total duration of the computation with 36 thread is 27 milliseconds.
Total duration of the computation with 37 thread is 20 milliseconds.
Total duration of the computation with 38 thread is 23 milliseconds.
Total duration of the computation with 39 thread is 26 milliseconds.
Total duration of the computation with 40 thread is 20 milliseconds.
Total duration of the computation with 41 thread is 30 milliseconds.
Total duration of the computation with 42 thread is 22 milliseconds.
Total duration of the computation with 43 thread is 20 milliseconds.
Total duration of the computation with 44 thread is 20 milliseconds.
Total duration of the computation with 45 thread is 20 milliseconds.
Total duration of the computation with 46 thread is 21 milliseconds.
Total duration of the computation with 47 thread is 26 milliseconds.
Total duration of the computation with 48 thread is 22 milliseconds.
Total duration of the computation with 49 thread is 22 milliseconds.
Total duration of the computation with 50 thread is 16 milliseconds.
Total duration of the computation with 51 thread is 14 milliseconds.
Total duration of the computation with 52 thread is 18 milliseconds.
Total duration of the computation with 53 thread is 12 milliseconds.
Total duration of the computation with 54 thread is 20 milliseconds.
Total duration of the computation with 55 thread is 21 milliseconds.
Total duration of the computation with 56 thread is 30 milliseconds.
Total duration of the computation with 57 thread is 30 milliseconds.
Total duration of the computation with 58 thread is 30 milliseconds.
Total duration of the computation with 59 thread is 25 milliseconds.
Total duration of the computation with 60 thread is 15 milliseconds.
Total duration of the computation with 61 thread is 10 milliseconds.
Total duration of the computation with 62 thread is 18 milliseconds.
Total duration of the computation with 63 thread is 12 milliseconds.
Total duration of the computation with 64 thread is 15 milliseconds.

Process finished with exit code 0

Например, время, необходимое для выполнения задачи с 7 потоками, одинаково с 64 потоками. Там что-то не так, но я не смог это исправить. Я уже тестировал программу без итерации, то есть путем ввода некоторых данных для общего количества потоков вручную, и ничего не изменилось. Функция run() выполняет только итерацию for, а MyThreadClass расширяет Thread класс Java. Я полагаю, мне нужен какой-то механизм, чтобы убить потоки после того, как они завершились, но я полагаю, что присоединение к ним уже делает это. Укажите на все, что вам кажется неправильным. Заранее спасибо.

Изменить: l oop внутри run() повторяется миллион раз. Вы можете сказать, что это фиксированная переменная эксперимента.

1 Ответ

0 голосов
/ 07 мая 2020

Вы можете создать собственный ThreadPoolExecutor, который будет отслеживать время выполнения каждой задачи, примерно так:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class TimeTrackingExecutor extends ThreadPoolExecutor  {

    private AtomicLong totalExecutionTime = new AtomicLong();
    ThreadLocal<Long> times = new ThreadLocal<>();

    public TimeTrackingExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        times.set(System.nanoTime());
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        long delta = System.nanoTime() -  times.get();
        totalExecutionTime.addAndGet(delta);
    }

    public long getTotalExecutionTime() {
        return totalExecutionTime.get();
    }

}

Методы beforeExecute и afterExecute, вызываемые до и после запуска каждого теста: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html

Изменяя размер ядра / максимального размера пула потоков, вы можете увидеть корреляцию с количеством потоков.

...