Mam stałą pulę wątków, do której przesyłam zadania (ograniczoną do 5 wątków). Jak mogę się dowiedzieć, który z tych 5 wątków wykonuje moje zadanie (na przykład „wątek nr 3 z 5 wykonuje to zadanie”)?
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?
}
}
% numThreads
zamiast tego należy użyćgetId()
jest14291
tam, gdziegetName()
dajepool-29-thread-7
, co uważam za bardziej przydatne.Odpowiedź zaakceptowanej odpowiedzi na pytanie o coraz to id wątku, ale nie pozwalają robić „Temat X z Y” wiadomości. Identyfikatory wątków są unikalne we wszystkich wątkach, ale niekoniecznie muszą zaczynać się od 0 lub 1.
Oto przykład pasujący do pytania:
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(); } }
i wyjście:
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
Niewielka zmiana przy użyciu arytmetyki modulo pozwoli ci poprawnie wykonać „wątek X z Y”:
// modulo gives zero-based results hence the +1 long threadId = Thread.currentThread().getId()%numThreads +1;
Nowe wyniki:
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
źródło
Możesz użyć Thread.getCurrentThread.getId (), ale dlaczego miałbyś to robić, gdy obiekty LogRecord zarządzane przez program rejestrujący mają już identyfikator wątku. Myślę, że brakuje gdzieś konfiguracji, która rejestruje identyfikatory wątków dla komunikatów dziennika.
źródło
Jeśli Twoja klasa dziedziczy po Thread , możesz użyć metod
getName
isetName
nazwać każdy wątek. W przeciwnym razie możesz po prostu dodaćname
pole doMyTask
i zainicjować je w swoim konstruktorze.źródło
Jeśli korzystasz z logowania, pomocne będą nazwy wątków. Pomaga w tym fabryka nici:
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++); } }
Wynik:
[ My thread # 0] Main INFO A pool thread is doing this task
źródło
Istnieje sposób pobierania bieżącego wątku:
Po uzyskaniu obiektu klasy Thread (t) możesz uzyskać potrzebne informacje za pomocą metod klasy Thread.
Pobieranie identyfikatora wątku:
long tId = t.getId(); // e.g. 14291
Pobieranie nazwy wątku:
String tName = t.getName(); // e.g. "pool-29-thread-7"
źródło