2010-07-20 16 views
112

Ich habe einen festen Thread-Pool, dem ich Aufgaben übertrage (begrenzt auf Threads). Wie kann ich herausfinden, welcher dieser Threads meine Aufgabe ausführt (etwas wie "Thread # 3 von macht diese Aufgabe")?Wie bekomme ich die Thread-ID aus einem Thread-Pool?

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

Antwort

182

Thread.currentThread() Verwendung:

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

das ist eigentlich nicht die gewünschte Antwort; man sollte '% numThreads' anstelle von – petrbel

+0

@petrbel verwenden Er beantwortet den Fragetitel perfekt, und die Thread-ID ist meiner Meinung nach nahe genug, wenn das OP" etwas wie Thread 3 von 5 "anfordert. – CorayThan

1

Wenn Ihre Klasse von Thread erbt, können Sie Methoden verwenden getName und setName jeden Thread zu nennen. Andernfalls könnten Sie einfach ein name Feld zu MyTask hinzufügen und es in Ihrem Konstruktor initialisieren.

6

Sie können Thread.getCurrentThread.getId() verwenden, aber warum sollten Sie das tun, wenn LogRecord Objekte, die vom Logger verwaltet werden, bereits über die Thread-ID verfügen. Ich denke, dass Sie irgendwo eine Konfiguration vermissen, die die Thread-IDs für Ihre Protokollnachrichten protokolliert.

22

Die angenommene Antwort beantwortet die Frage über eine Thread-ID, aber es lässt Sie nicht "Thread X Y" Nachrichten. Thread-IDs sind eindeutig über Threads aber nicht unbedingt starten von 0 oder 1

Hier ist ein Beispiel für: die Frage:

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

und die Ausgabe:

[email protected]:/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 

Eine leichte zwicken Mit Hilfe der Modulo-Arithmetik können Sie "Gewinde X von Y" korrekt ausführen:

Neue Ergebnisse :

[email protected]:/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 
+4

Sind Java-Thread-IDs garantiert zusammenhängend? Wenn nicht, wird Ihr Modulo nicht korrekt funktionieren. –

+0

@BrianGordon Nicht sicher über eine Garantie, aber der Code scheint nicht mehr als eine interne Zähler erhöhen: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/ java/lang/Thread.java # l217 –

+5

Wenn also zwei Thread-Pools gleichzeitig initialisiert wurden, haben die Threads in einem dieser Thread-Pools möglicherweise IDs von beispielsweise 1, 4, 5, 6, 7 und in diesem Fall würden Sie das tun habe zwei verschiedene Threads mit der gleichen "Ich bin Thread n von 5" Nachricht. –

0

Wenn Sie Protokollierung verwenden, dann sind Thread-Namen hilfreich. Ein Thread Fabrik hilft mit diesem:

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

Ausgang:

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