0

在我正在工作的 Java 代码的某个部分中,我需要在方法中放置一个计时器run()。每个线程都会执行里面的所有代码run()。但是我需要在块(1)之后和代码块(2)之前开始测量,所以需要在那里触发计时器。

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);

但是所有线程都有自己的begin变量并启动计数器,这是一个问题,因为System.currentTimeMillis()应该触发一次而不是由许多线程触发。我可能可以将run()两个不同并行区域的代码分开,但意味着创建线程两次,这是不可接受的(就性能而言)。#pragma omp master使用 Java 线程的 Java有类似的 OpenMP 指令技术吗?我怎样才能在这里正确测量时间?

4

2 回答 2

1

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

if (id == YOUR_THREAD_ID) 
{
     begin = System.currentTimeMillis();
}
于 2017-04-29T19:41:42.883 回答
1

The simplest way would just be to record the time in the master thread (i.e. the thread which creates all the children) instead of in the children themselves.

But if you really want to start the timer in the children (maybe there's some expensive setup?), you could use a Guava StopWatch object.

The code would look something like:

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));
于 2017-05-01T01:50:46.413 回答