थ्रेड आईडी थ्रेड पूल से कैसे प्राप्त करें?


131

मेरे पास एक निश्चित थ्रेड पूल है जिसे मैं कार्यों को प्रस्तुत करता हूं ( 5 धागे तक सीमित )। मैं यह कैसे पता लगा सकता हूं कि उन 5 थ्रेड्स में से कौन सा मेरा कार्य निष्पादित करता है (कुछ ऐसा है जैसे "थ्रेड # 3 ऑफ 5 इस कार्य को कर रहा है")?

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

जवाबों:


230

का उपयोग कर Thread.currentThread():

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

3
यह वास्तव में वांछित उत्तर नहीं है; % numThreadsइसके बजाय का उपयोग करना चाहिए
पेट्रेल

2
@petrbel वह पूरी तरह से प्रश्न शीर्षक का जवाब दे रहा है, और ओपी आईडी मेरी राय में काफी करीब है, जब ओपी "थ्रेड # 3 ऑफ 5" जैसा कुछ अनुरोध करता है।
कोरेथन

ध्यान दें, एक उदाहरण आउटपुट getId()है 14291जहां getName()आप देता है pool-29-thread-7, जो मैं तर्क देता हूं कि यह अधिक उपयोगी है।
जोशुआ पिंटर

26

स्वीकार किए जाते हैं जवाब करने के बारे में सवाल का जवाब एक धागा आईडी, लेकिन यह तुम क्या नहीं करता संदेशों "वाई के थ्रेड एक्स"। थ्रेड आईडी थ्रेड में अद्वितीय हैं, लेकिन जरूरी नहीं कि यह 0 या 1 से शुरू हो।

यहाँ एक प्रश्न का मिलान उदाहरण है:

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

और आउटपुट:

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

Modulo arithmetic का उपयोग करने वाला एक मामूली ट्विक आपको "Y का धागा X" सही ढंग से करने की अनुमति देगा:

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

नए परिणाम:

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 

5
क्या जावा थ्रेड आईडी सन्निहित होने की गारंटी है? यदि नहीं, तो आपका मोड्यूल सही से काम नहीं करेगा।
ब्रायन गॉर्डन

@BrianGordon एक गारंटी के बारे में निश्चित नहीं है, लेकिन कोड एक आंतरिक काउंटर को बढ़ाने के अलावा और कुछ नहीं लगता है: hg.openjdk.java.net/jdk8/jdk8/jdk/fdile/687fd7c7986d/src/share/…
बुरहान अली

6
इसलिए यदि दो थ्रेड पूल को एक साथ इनिशियलाइज़ किया गया था, तो उन थ्रेड पूल में से एक में थ्रेड्स की आईडी हो सकती है, उदाहरण के लिए, 1, 4, 5, 6, 7 और उस स्थिति में आपके पास एक ही साथ दो अलग-अलग धागे होंगे "मैं हूँ 5 "संदेश का धागा n।
ब्रायन गॉर्डन

@BrianGordon Thread.nextThreadID () सिंक्रनाइज़ है, इसलिए यह समस्या नहीं होगी, है ना?
माथियस अजेवेदो

@MatheusAzevedo जिसका इससे कोई लेना देना नहीं है।
ब्रायन गॉर्डन

6

आप Thread.getCurrentThread.getId () का उपयोग कर सकते हैं, लेकिन आप ऐसा क्यों करना चाहते हैं जब LogRecord ऑब्जेक्ट्स द्वारा प्रबंधित लकड़हारा पहले से ही थ्रेड आईडी है। मुझे लगता है कि आप कहीं एक कॉन्फ़िगरेशन याद कर रहे हैं जो आपके लॉग संदेशों के लिए थ्रेड आइडीएस लॉग करता है।


1

यदि आपकी कक्षा थ्रेड से विरासत में मिली है , तो आप विधियों का उपयोग कर सकते हैं getNameऔर setNameप्रत्येक थ्रेड का नाम दे सकते हैं । अन्यथा आप बस अपने nameक्षेत्र में एक फ़ील्ड जोड़ सकते हैं MyTaskऔर इसे इनिशियलाइज़ कर सकते हैं।


1

यदि आप लॉगिंग का उपयोग कर रहे हैं तो थ्रेड नाम मददगार होंगे। एक धागा कारखाना इसके साथ मदद करता है:

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

आउटपुट:

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

1

वर्तमान थ्रेड प्राप्त करने का तरीका है:

Thread t = Thread.currentThread();

आपके द्वारा थ्रेड क्लास ऑब्जेक्ट (टी) प्राप्त करने के बाद आप थ्रेड क्लास के तरीकों का उपयोग करने के लिए आवश्यक जानकारी प्राप्त कर सकते हैं।

थ्रेड आईडी मिल रही है:

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

धागा नाम गेटिंग:

String tName = t.getName(); // e.g. "pool-29-thread-7"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.