কোনও থ্রেড পুল থেকে থ্রেড আইডি কীভাবে পাবেন?


131

আমার কাছে একটি স্থির থ্রেড পুল রয়েছে যা আমি কাজগুলি জমা করি ( 5 টি থ্রেডের মধ্যে সীমাবদ্ধ )। আমি কিভাবে জানতে পারবেন ঐ এক যা 5 থ্রেড executes আমার কাজে (ভালো কিছু "থ্রেড # 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
@ পিটারবেল তিনি প্রশ্নের শিরোনামের পুরোপুরি উত্তর দিচ্ছেন, এবং যখন ওপি "'থ্রেড # 3 এর মতো' কিছু অনুরোধ করে তখন থ্রেড আইডিটি আমার মতে যথেষ্ট কাছে।
CorayThan

দ্রষ্টব্য, একটি উদাহরণ আউটপুট 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 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
জাভা থ্রেড আইডি কি সামঞ্জস্যপূর্ণ হওয়ার গ্যারান্টিযুক্ত? যদি তা না হয় তবে আপনার মডুলো সঠিকভাবে কাজ করবে না।
ব্রায়ান গর্ডন

@ ব্রায়ান গর্ডন কোনও গ্যারান্টি সম্পর্কে নিশ্চিত নন, তবে কোডটি অভ্যন্তরীণ কাউন্টারকে বাড়ানোর চেয়ে বেশি কিছু বলে মনে হচ্ছে না: hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…
বুরহান আলী

6
সুতরাং যদি দুটি থ্রেড পুল একই সাথে আরম্ভ করা হয় তবে thread থ্রেড পুলগুলির একটিতে থ্রেডের আইডি থাকতে পারে, উদাহরণস্বরূপ, 1, 4, 5, 6, 7 এবং সেই ক্ষেত্রে আপনার একই "আমি আছি সহ দুটি পৃথক থ্রেড থাকবে 5 এর থ্রেড এন "বার্তা।
ব্রায়ান গর্ডন

@ ব্রায়ান গর্ডন থ্রেড.নেক্সটথ্রেডআইডি () সিঙ্ক্রোনাইজ করা হয়েছে, তাই এটি কোনও সমস্যা হবে না, তাই না?
ম্যাথিউস আজেভেদো

@ ম্যাথিউস আজেভেদো এর সাথে কিছু করার নেই।
ব্রায়ান গর্ডন

6

আপনি থ্রেড.গেটকারেন্টারত্রেড.ড্যাডআইডি () ব্যবহার করতে পারেন তবে লগারের দ্বারা পরিচালিত লগ রেকর্ড অবজেক্টগুলির ইতিমধ্যে থ্রেড আইডি থাকলে আপনি কেন এটি করতে চান । আমি মনে করি আপনি কোথাও একটি কনফিগারেশন মিস করছেন যা আপনার লগ বার্তাগুলির জন্য থ্রেড আইডিতে লগ করে।


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"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.