在Thread区域中仅执行一次代码

时间:2017-04-29 18:21:19

标签: java performance openmp hpc performance-measuring

在我正在使用的Java代码的某个部分中,我需要在run()方法中放置一个计时器。每个线程都将执行for (int i = 0; i < total_threads-1; i++){ final int id = i+1; th[i] = new Thread(new Runnable() { public final void run(){ /* ... block of code (1) executed by multiple threads ... */ /* How can i start this counter only once? */ final long begin = System.currentTimeMillis(); /* ... another block of code (2) executed by multiple threads i need to measure!!! ... */ } }); th[i].start(); } for(int i = 0 ; i < total_threads-1 ; i++) { try { th[i].join(); } catch (InterruptedException e) {} } final long end = System.currentTimeMillis(); System.out.println((end-begin) / 1000.0); 内的所有代码。但我需要在块(1)之后和代码块(2)之前开始测量,因此需要在那里触发定时器。

begin

但是所有线程都有自己的System.currentTimeMillis()变量并启动计数器,这是一个问题,因为run()应该被触发一次而不是被许多线程触发。 我可能会在两个不同的并行区域中分离#pragma omp master的代码,但意味着创建两次线程,这是不可接受的(在性能方面)。 对于使用Java线程的Java,有一种类似的OpenMP指令views: { agendaDay: { type: 'agenda', duration: { days: 1 }, titleFormat: 'ddd D MMMM YYYY', slotLabelFormat: 'HH:mm', slotDuration: '00:15:00', groupByResource: true }, agendaTwoDay: { type: 'agenda', duration: { days: 2 }, titleFormat: 'ddd D MMMM YYYY', slotLabelFormat: 'HH:mm', slotDuration: '00:15:00', groupByResource: true }, agendaWeek: { type: 'agenda', duration: { weeks: 1 }, titleFormat: 'ddd D MMMM YYYY', slotLabelFormat: 'HH:mm', slotDuration: '00:15:00', groupByResource: true } } 技术? 我如何在这里正确测量时间?

2 个答案:

答案 0 :(得分:1)

您可以检查线程ID以执行prefer行一次:

if (id == YOUR_THREAD_ID) 
{
     begin = System.currentTimeMillis();
}

答案 1 :(得分:1)

最简单的方法就是在主线程(即创建所有子节点的线程)中记录时间而不是在子节点中记录时间。

但是如果你真的想在孩子们中启动计时器(可能还有一些昂贵的设置?),你可以使用Guava StopWatch对象。

代码看起来像:

StopWatch timer = StopWatch.createUnstarted();
for (int i = 0; i < total_threads-1; i++){
    final int id = i+1;
    th[i] = new Thread(() -> {
        /* ... block of code (1) executed by multiple threads ... */

        try {
            synchronized (timer) {
                timer.start();
            }
        } catch (IllegalStateException e) {
            // ignore; the watch is already started
        }

        /* ... another block of code (2) executed by multiple threads i need to measure!!! ... */
    });
    th[i].start();
}

for(int i = 0 ; i < total_threads-1 ; i++) {
    try {
        th[i].join();
    } catch (InterruptedException e) {}
}

timer.stop();

System.out.println(timer.elapsed(TimeUnit.SECONDS));