【问题标题】:Get Thread By Name按名称获取线程
【发布时间】:2013-02-28 11:47:00
【问题描述】:

我有一个多线程应用程序,我通过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;
}

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

【问题讨论】:

  • 线程是如何创建的?
  • 只需将您需要的线程按名称存储在HashMap&lt;String, Thread&gt; 中。
  • @JohnVint 线程正在另一个类中创建,所以我无法直接访问它们。
  • @DKN 听起来你需要一个单身人士。
  • @DKN 真的没有通用的例子。当然你知道如何使用HashMaps,所以有一个作为线程注册表,可以在 1. 创建线程的位置和 2. 您需要检索它们的位置访问。这两个在很大程度上取决于您的应用程序的内部结构。

标签: java android multithreading


【解决方案1】:

Pete 回答的迭代..

public Thread getThreadByName(String threadName) {
    for (Thread t : Thread.getAllStackTraces().keySet()) {
        if (t.getName().equals(threadName)) return t;
    }
    return null;
}

【讨论】:

    【解决方案2】:

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

    • 获取当前线程的组
    • 通过调用ThreadGroup.getParent() 沿着线程组层次结构向上移动,直到找到一个父级为空的组。
    • 调用ThreadGroup.enumerate() 查找系统上的所有线程。

    这样做的价值完全让我无法理解......您可能会用命名线程做什么?除非您在实现 Runnable 时继承了 Thread(从一开始就是草率的编程)。

    【讨论】:

    • 一个用例是找到一个定义在第三方库(意味着源代码不能轻易修改)中的局部变量线程(意味着反射无法到达它),其名称指定为设置一个未捕获的异常处理程序(因为在此处抛出异常时它们不允许记录)。这是一个非常特殊的情况,但这种情况也有边缘情况。
    • 在我的例子中,我用它来编写一个单元测试来调试一个疑似线程安全问题的线程。有问题的线程实现了 Runnable,但问题是:替代答案是什么?如何通过名称获取特定的 Runnable?
    【解决方案3】:

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

    Iterator<Thread> i = threadSet.iterator();
    while(i.hasNext()) {
      Thread t = i.next();
      if(t.getName().equals(threadName)) return t;
    }
    return null;
    

    【讨论】:

    • 这个和上面的例子一样,如果线程被打断了就不行了!
    【解决方案4】:

    这就是我在this的基础上做的:

    /*
        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;
    }
    

    【讨论】:

    • 当你有直接的 API 时,没有理由通过 JMX 接口来做。
    猜你喜欢
    • 2015-02-15
    • 2012-04-24
    • 1970-01-01
    • 2014-07-27
    • 2016-03-26
    • 2012-03-11
    • 2011-07-02
    • 1970-01-01
    相关资源
    最近更新 更多