Java 如何从线程池中获取线程ID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3294293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:49:06  来源:igfitidea点击:

How to get thread id from a thread pool?

javamultithreadingthreadpoolexecutorserviceexecutors

提问by serg

I have a fixed thread pool that I submit tasks to (limited to 5threads). How can I find out which one of those 5threads executes my task (something like "thread #3 of 5is doing this task")?

我有一个固定的线程池,我向它提交任务(限制为5 个线程)。如何找出这5 个线程中的哪一个执行我的任务(类似于“线程 #3 of 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?
    }
}

采纳答案by skaffman

Using Thread.currentThread():

使用Thread.currentThread()

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

回答by Justin Ethier

If your class inherits from Thread, you can use methods getNameand setNameto name each thread. Otherwise you could just add a namefield to MyTask, and initialize it in your constructor.

如果您的类继承自Thread,您可以使用方法getNamesetName命名每个线程。否则,您可以向 中添加一个name字段MyTask,并在您的构造函数中对其进行初始化。

回答by Vineet Reynolds

You can use Thread.getCurrentThread.getId(), but why would you want to do that when LogRecordobjects managed by the logger already have the thread Id. I think you are missing a configuration somewhere that logs the thread Ids for your log messages.

您可以使用 Thread.getCurrentThread.getId(),但是当记录器管理的LogRecord对象已经具有线程 ID时,您为什么要这样做。我认为您在某处缺少记录日志消息的线程 ID 的配置。

回答by Burhan Ali

The accepted answer answers the question about getting athread id, but it doesn't let you do "Thread X of Y" messages. Thread ids are unique across threads but don't necessarily start from 0 or 1.

接受的答案回答了关于获取问题一个线程ID,但它不会让你的邮件“Y的主题X”。线程 ID 跨线程是唯一的,但不一定从 0 或 1 开始。

Here is an example matching the question:

这是一个匹配问题的示例:

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

and the output:

和输出:

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

A slight tweak using modulo arithmetic will allow you to do "thread X of Y" correctly:

使用模运算稍作调整将允许您正确执行“Y 的线程 X”:

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

New results:

新结果:

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 

回答by Vitaliy Polchuk

If you are using logging then thread names will be helpful. A thread factory helps with this:

如果您正在使用日志记录,则线程名称会有所帮助。线程工厂有助于解决此问题:

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

Output:

输出:

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

回答by Serg.Stankov

There is the way of current thread getting:

当前线程的获取方式有:

Thread t = Thread.currentThread();

After you have got Thread class object (t) you are able to get information you need using Thread class methods.

获得 Thread 类对象 (t) 后,您就可以使用 Thread 类方法获取所需的信息。

Thread ID gettting:

线程 ID 获取:

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

Thread name gettting:

线程名称获取:

String tName = t.getName(); // e.g. "pool-29-thread-7"