Domanda

Ho un pool di filetto fisso che invia i compiti a (limitato a 5 Threads).Come posso scoprire quale di quei 5 Threads esegue la mia attività (qualcosa come "Thread # 3 di 5 sta facendo questa attività")?

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?
    }
}
.

È stato utile?

Soluzione

Utilizzo di Thread.currentThread():

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

Altri suggerimenti

La risposta accettata risponde alla domanda su Ottenere A ID thread, ma non ti consente di eseguire messaggi "thread x di y".ID Thread sono unici tra i thread ma non dovrebbero necessariamente iniziare da 0 o 1.

Ecco un esempio che corrisponde alla domanda:

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

e l'uscita:

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 leggero tweak usando Modulo Arithmetic ti consentirà di eseguire correttamente "thread x di y":

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

Nuovi risultati:

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 
.

Puoi usare thread.getcurrentthread.getId (), ma perché vorresti farlo quando Logrecord Gli oggetti gestiti dal logger hanno già l'ID filettatura.Penso che ti manca una configurazione da qualche parte che registra gli ID thread per i tuoi messaggi di registro.

Se la tua classe eredita da Thread , è possibile utilizzare i metodi getName e setName per nominare ogni discussione.Altrimenti è possibile aggiungere un campo name a MyTask e inizializzarlo nel costruttore.

Se si utilizza la registrazione, i nomi dei thread saranno utili. Una fabbrica di thread aiuta con questo:

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

Uscita:

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

C'è il modo di ottenere il thread corrente:

Thread t = Thread.currentThread();
.

Dopo aver ottenuto l'oggetto classe Thread (T) è possibile ottenere informazioni necessarie utilizzando i metodi di classe Thread.

ID thread Getting:

long tId = t.getId(); // e.g. 14291
.

Nome discussione Getting:

String tName = t.getName(); // e.g. "pool-29-thread-7"
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top