En cierta parte de un código Java en el que estoy trabajando, necesito colocar un temporizador dentro de un método run() . Cada hilo ejecutará todo el código dentro run() . Pero necesito comenzar a medir después del bloque (1) y antes del bloque de código (2), por lo que el temporizador debe activarse allí.
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); Pero todos los subprocesos tendrán su propia variable de begin e iniciarán el contador, lo cual es un problema porque System.currentTimeMillis() debe activarse una vez y no por muchos subprocesos. Probablemente podría separar el código de run() en dos regiones paralelas diferentes, pero implicaría crear los subprocesos dos veces, lo que sería inaceptable (en términos de rendimiento). ¿Existe una técnica similar a la directiva OpenMP #pragma omp master para Java usando subprocesos de Java? ¿Cómo puedo medir el tiempo correctamente aquí?
Puede verificar la ID del hilo para ejecutar la línea preferida una vez:
if (id == YOUR_THREAD_ID) { begin = System.currentTimeMillis(); }La forma más sencilla sería registrar el tiempo en el subproceso maestro (es decir, el subproceso que crea todos los hijos) en lugar de en los propios hijos.
Pero si realmente desea iniciar el temporizador en los niños (¿quizás haya alguna configuración costosa?), Podría usar un objeto Guava StopWatch .
El código sería algo como:
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));