Как измерить производительность кода в многопоточном приложении? - PullRequest
0 голосов
/ 11 июня 2018

В настоящее время я работаю над проектом, в котором я не использую никаких инструментов измерения производительности для вычисления времени, необходимого для выполнения кода.

Вместо этого я использую long <variableName> = System.nanoTime(); в начале и в концекода и вычитая их, чтобы получить время, необходимое для завершения выполнения.

Он работал нормально, пока я не начал использовать его в многопоточном коде.

public class DataEntry {


    public static void main(String[] args) {

        long l = System.nanoTime();

        /*
        *  Regular Multithreading code to generate 'n' number of threads to
        *  perform a certain task.
        */


        System.out.println("Total Execution Time Is : "+((System.nanoTime()-l)/1000000.0)+" milli seconds");
    }
}

Проблема, с которой я здесь сталкиваюсь, заключается в том, что мой main() поток завершает работу задолго до того, как созданные пользователем потоки закончили свои задачи.

Я имею в виду, что я получаю вывод примерно такого ...

Total Execution Time Is : 9.600147 milli seconds
Thread#1 :  Execution Over Bye Bye
Thread#2 :  Execution Over Bye Bye
Thread#3 :  Execution Over Bye Bye
Thread#4 :  Execution Over Bye Bye
Thread#5 :  Execution Over Bye Bye

Все потоки child дают свои соответствующие последние пару секунд после того, как main() завершил выполнение

Я понимаю, что все потоки работают независимо друг от друга и что мы можем сделать main sleep () до тех пор, пока все потоки child не завершат свои выполнения.

Мне было интересно,естьспособ сделать это таким способом, который позволил бы мне не допустить, чтобы какой-либо поток ожидал друг друга, таким образом, что последний поток, который заканчивает свое выполнение, отвечает за возвращение мне окончательного времени выполнения.

Послеэто код

DataEntry.java

public class DataEntry {

    public static void main(String[] args) {

        long l = System.nanoTime();

//STRING THAT WILL BE USED TO DOWNLOAD THE MULTIPLE FILES

        String[] strDownload = {"https://unsplash.com/photos/n61ur6rT_F8/download?force=true",
                    "https://unsplash.com/photos/GLS3mY37RPo/download?force=true",
                    "https://unsplash.com/photos/v6asLq_dYzw/download?force=true",
                    "https://unsplash.com/photos/ePB2oGU8mb4/download?force=true",
                    "https://unsplash.com/photos/yEHQfGNKnZ4/download?force=true"};


        //CREATE A FIXED NUMBER OF THREADS BASED ON THE LENGTH OF THE INPUT STRING ARRAY
            for (int i = 0; i < strDownload.length; i++) {
                Thread t = new Thread(new ThreadsGeneration(strDownload[i]));   //PASSING THE i'th ELEMENT OF THE ARRAY AS THE PARAMETER FOR THE CONSTRUCTOR
                t.start();                                                      //CREATE THE THREAD
                System.out.println(t.getName()+"\n");

            }

            System.out.println("Total Execution Time Is : "+((double)(System.nanoTime()-l)/1000000)+" milli seconds");
        }
    }

ThreadGeneration.java

public class ThreadsGeneration implements Runnable{

    private static String string;

    public ThreadsGeneration(String string) {
        ThreadsGeneration.string = string;
    }

    @Override
    public void run() {
        System.out.println("Inside RUN");
        DownloadManager.getData(string);

    }   
}

DownloadManager.Ява

public class DownloadManager {


    public static void getData(String strDownload) {


        String strDestination = "C:\\Users\\admin\\Desktop\\"+Math.random()+".jpg";

        try {       

            printData(strDownload,strDestination);

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    private static synchronized void printData(String strDownload, String strDestination) throws Exception {

        URL url = new URL(strDownload);
        ReadableByteChannel rbc = Channels.newChannel(url.openConnection().getInputStream());
        FileOutputStream fos = new FileOutputStream(strDestination);
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
        fos.close();
        rbc.close();
        System.out.println("Everything done");
    }
}

1 Ответ

0 голосов
/ 11 июня 2018

Я могу придумать два способа:

  1. Присоединить все потоки к основному потоку, вызвав .join(), а затем распечатать время, необходимое для присоединения всех потоков.Таким образом, основной поток легко напечатает время, которое заняло.

    В этом случае Main не спит.Это просто ждет.

  2. Попросите ваши потоки напечатать время, которое они взяли, в конце кода, который они запускают.Таким образом, вы сможете увидеть индивидуальное время каждого потока и потратить несколько мозговых циклов на подсчет общего времени выполнения самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...