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


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.