28

我有一个多线程应用程序,我通过setName()属性为每个线程分配一个唯一的名称。现在,我希望功能可以直接使用相应的名称访问线程。

类似于以下功能:

public Thread getThreadByName(String threadName) {
    Thread __tmp = null;

    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);

    for (int i = 0; i < threadArray.length; i++) {
        if (threadArray[i].getName().equals(threadName))
            __tmp =  threadArray[i];
    }

    return __tmp;
}

上述函数检查所有正在运行的线程,然后从正在运行的线程集中返回所需的线程。也许我想要的线程被中断了,那么上面的函数就不起作用了。关于如何合并该功能的任何想法?

4

4 回答 4

25

皮特答案的迭代..

public Thread getThreadByName(String threadName) {
    for (Thread t : Thread.getAllStackTraces().keySet()) {
        if (t.getName().equals(threadName)) return t;
    }
    return null;
}
于 2014-12-11T01:59:21.953 回答
23

您可以使用ThreadGroup找到所有活动线程:

  • 获取当前线程的组
  • ThreadGroup.getParent()通过调用直到找到具有空父组的组,沿着线程组层次结构向上工作。
  • 调用ThreadGroup.enumerate()以查找系统上的所有线程。

这样做的价值完全让我无法理解......你可能会用命名线程做什么?除非你在Thread应该实现的时候进行子类Runnable化(从一开始就是草率的编程)。

于 2013-03-12T19:48:48.100 回答
6

我最喜欢 HashMap 的想法,但是如果你想保留 Set,你可以迭代 Set,而不是通过转换为数组的设置:

Iterator<Thread> i = threadSet.iterator();
while(i.hasNext()) {
  Thread t = i.next();
  if(t.getName().equals(threadName)) return t;
}
return null;
于 2013-03-12T19:30:23.257 回答
0

这就是我在此基础上的做法

/*
    MIGHT THROW NULL POINTER
 */
Thread getThreadByName(String name) {
    // Get current Thread Group
    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    ThreadGroup parentThreadGroup;
    while ((parentThreadGroup = threadGroup.getParent()) != null) {
        threadGroup = parentThreadGroup;
    }
    // List all active Threads
    final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    int nAllocated = threadMXBean.getThreadCount();
    int n = 0;
    Thread[] threads;
    do {
        nAllocated *= 2;
        threads = new Thread[nAllocated];
        n = threadGroup.enumerate(threads, true);
    } while (n == nAllocated);
    threads = Arrays.copyOf(threads, n);
    // Get Thread by name
    for (Thread thread : threads) {
        System.out.println(thread.getName());
        if (thread.getName().equals(name)) {
            return thread;
        }
    }
    return null;
}
于 2018-03-11T17:57:46.197 回答