web-dev-qa-db-fra.com

Comment obtenir un identifiant de thread à partir d'un pool de threads?

J'ai un pool de threads fixe auquel je soumets des tâches (limité à 5 threads). Comment puis-je savoir lequel de ces 5 threads exécute ma tâche (quelque chose comme "le thread n ° 3 sur 5 effectue cette tâche")?

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?
    }
}
121
serg

Utilisation de Thread.currentThread():

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

La réponse acceptée répond à la question sur l'obtention de un id de fil, mais elle ne vous permet pas de faire des messages "Thread X of Y". Les identifiants de threads sont uniques pour tous les threads mais ne commencent pas nécessairement à 0 ou 1.

Voici un exemple correspondant à la question:

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

et la sortie:

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 léger tweak utilisant l’arithmétique modulo vous permettra de faire le "thread X" correctement:

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

Nouveaux résultats:

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 
25
Burhan Ali

Vous pouvez utiliser Thread.getCurrentThread.getId (), mais pourquoi voudriez-vous le faire lorsque LogRecord les objets gérés par le consignateur ont déjà l’ID de thread. Je pense qu'il vous manque une configuration quelque part qui enregistre les ID de thread pour vos messages de journalisation.

6
Vineet Reynolds

Si votre classe hérite de Thread , vous pouvez utiliser les méthodes getName et setName pour nommer chaque thread. Sinon, vous pouvez simplement ajouter un champ name à MyTask et l'initialiser dans votre constructeur.

1
Justin Ethier

Si vous utilisez la journalisation, les noms de threads vous seront utiles .

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

Sortie:

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

Il y a le moyen d'obtenir le fil actuel:

Thread t = Thread.currentThread();

Après avoir obtenu un objet de classe Thread (t), vous pouvez obtenir les informations dont vous avez besoin à l’aide des méthodes de la classe Thread.

Identifiant de filetage

long tId = t.getId();

Nom du fil de discussion 

String tName = t.getName();
0
Serg.Stankov