thread hilos example create java multithreading threadpool executorservice executors

java - hilos - ¿Cómo obtener el id. De subproceso de un grupo de subprocesos?



thread java 8 (5)

Tengo un grupo de hilos fijo al que envío tareas (limitado a 5 hilos). ¿Cómo puedo saber cuál de esos 5 hilos ejecuta mi tarea (algo como "el hilo 3 de 5 está haciendo esta tarea")?

ExecutorService taskExecutor = Executors.newFixedThreadPool(5); //in infinite loop: taskExecutor.execute(new MyTask()); .... private class MyTask implements Runnable { public void run() { logger.debug("Thread # XXX is doing this task");//how to get thread id? } }


La respuesta aceptada responde a la pregunta sobre cómo obtener un ID de hilo, pero no le permite hacer mensajes de "Subproceso X de Y". Los identificadores de subprocesos son únicos entre los subprocesos, pero no necesariamente comienzan desde 0 o 1.

Aquí hay un ejemplo que coincide con la pregunta:

import java.util.concurrent.*; class ThreadIdTest { public static void main(String[] args) { final int numThreads = 5; ExecutorService exec = Executors.newFixedThreadPool(numThreads); for (int i=0; i<10; i++) { exec.execute(new Runnable() { public void run() { long threadId = Thread.currentThread().getId(); System.out.println("I am thread " + threadId + " of " + numThreads); } }); } exec.shutdown(); } }

y el resultado:

burhan@orion:/dev/shm$ javac ThreadIdTest.java && java ThreadIdTest I am thread 8 of 5 I am thread 9 of 5 I am thread 10 of 5 I am thread 8 of 5 I am thread 9 of 5 I am thread 11 of 5 I am thread 8 of 5 I am thread 9 of 5 I am thread 10 of 5 I am thread 12 of 5

Un ligero ajuste usando la aritmética de módulo le permitirá hacer "hilo X de Y" correctamente:

// modulo gives zero-based results hence the +1 long threadId = Thread.currentThread().getId()%numThreads +1;

Nuevos resultados:

burhan@orion:/dev/shm$ javac ThreadIdTest.java && java ThreadIdTest I am thread 2 of 5 I am thread 3 of 5 I am thread 3 of 5 I am thread 3 of 5 I am thread 5 of 5 I am thread 1 of 5 I am thread 4 of 5 I am thread 1 of 5 I am thread 2 of 5 I am thread 3 of 5


Puede usar Thread.getCurrentThread.getId (), pero ¿por qué querría hacer eso cuando los objetos LogRecord administrados por el registrador ya tienen el Id del hilo? Creo que te falta una configuración en algún lugar que registra los Id de la secuencia para tus mensajes de registro.


Si está utilizando el registro, los nombres de los hilos serán útiles. Una fábrica de hilos ayuda con esto:

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; public class Main { static Logger LOG = LoggerFactory.getLogger(Main.class); static class MyTask implements Runnable { public void run() { LOG.info("A pool thread is doing this task"); } } public static void main(String[] args) { ExecutorService taskExecutor = Executors.newFixedThreadPool(5, new MyThreadFactory()); taskExecutor.execute(new MyTask()); taskExecutor.shutdown(); } } class MyThreadFactory implements ThreadFactory { private int counter; public Thread newThread(Runnable r) { return new Thread(r, "My thread # " + counter++); } }

Salida:

[ My thread # 0] Main INFO A pool thread is doing this task


Si su clase hereda de Thread , puede usar los métodos getName y setName para nombrar cada hilo. De lo contrario, podría agregar un campo de name a MyTask e inicializarlo en su constructor.


Usando Thread.currentThread() :

private class MyTask implements Runnable { public void run() { long threadId = Thread.currentThread().getId(); logger.debug("Thread # " + threadId + " is doing this task"); } }