Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取使用指定Runnable运行的所有线程_Java_Multithreading_Concurrent Programming - Fatal编程技术网

Java 获取使用指定Runnable运行的所有线程

Java 获取使用指定Runnable运行的所有线程,java,multithreading,concurrent-programming,Java,Multithreading,Concurrent Programming,我有一个Runnable,被多个线程使用: Runnable myRunnable = new MyWorker(); Thread one = new Thread(myRunnable); Thread two = new Thread(myRunnable); one.start(); two.start(); 如何获取使用myRunnable创建的所有线程 (当然,这个例子被简化了。我在不同类的多个地方用myRunnable创建了新线程。) 用例(根据请求):MyWorkerOfMyP

我有一个Runnable,被多个线程使用:

Runnable myRunnable = new MyWorker();
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
如何获取使用
myRunnable
创建的所有线程

(当然,这个例子被简化了。我在不同类的多个地方用
myRunnable
创建了新线程。)


用例(根据请求):
MyWorkerOfMyPage
是绑定到页面的延迟工作程序。如果用户离开此页面(例如,通过导航到另一页面),则属于
MyWorkerOfMyPage
的所有线程都应被意外终止,因为不再需要它们的结果。

最好的方法是自己跟踪。例如,使用全局单例来启动线程并跟踪您启动的线程。

在Java中,没有简单的方法可以找到对象引用的所有位置,您必须维护自己的集合

如果您想静态地了解这一点,可以在ide中找到用法

如果您想动态地了解这一点,可以让Runnable将线程添加到集合中(完成后将其删除)


一般来说,开发人员只应故意创建线程。i、 开发人员应该知道他/她什么时候创建线程以及这些线程将做什么。如果你有一个好的设计,就不应该在运行时跟踪它。

虽然我的第一个想法是@Bengt的,但是如果你有一个可运行程序列表,并且你只想知道哪些程序使用你的接口,也许你可以使用Class.isAssignableFrom


如前所述,最好的方法是自己跟踪。这迫使你对自己正在做的事情有一个清晰的理解。如果您使用线程,这是一件好事。。。六羟甲基三聚氰胺六甲醚。。。在任何情况下都是好事;)

但是,如果您真的想检测线程,您可以使用Thread类的反射来获取所需的信息。首先使方法“getThreads”可访问以获取所有正在运行的线程,然后使字段“target”可访问以获取线程的可运行性

下面是一个示例程序(但我建议不要在实际应用程序中使用。您现在应该知道您正在启动哪些线程,这可能会损害与未来JDK的兼容性,可能会损害可移植性…)

import java.lang.reflect.Field;
导入java.lang.reflect.Method;
导入java.util.ArrayList;
导入java.util.List;
公共班机{
公共静态void main(字符串[]args)引发异常{
Runnable myRunnable=新Runnable(){
@凌驾
公开募捐{
试一试{
System.out.println(“开始:+Thread.currentThread().getName());
睡眠(100);
}捕捉(中断异常e){
抛出新的运行时异常(e);
}
}
};
线程一=新线程(myRunnable);
线程2=新线程(myRunnable);
一、启动();
二、启动();
List threads=getThreadsFor(myRunnable);
用于(线程:线程)
System.out.println(“找到:+thread.getName());
}
私有静态列表getThreadsFor(Runnable myRunnable)引发异常{
方法getThreads=Thread.class.getDeclaredMethod(“getThreads”);
字段目标=Thread.class.getDeclaredField(“目标”);
target.setAccessible(true);
getThreads.setAccessible(true);
线程[]线程=(线程[])getThreads.invoke(null);
列表结果=新建ArrayList();
用于(线程:线程){
Object runnable=target.get(线程);
如果(runnable==myRunnable)
结果。添加(线程);
}
返回结果;
}
}

您使用的是哪种ide?如果您可以更新您的问题“为什么”需要此功能,那就太好了。我可以建议如何使用此功能(就像10行代码),但如果您告诉我为什么需要此功能,请立即使用案例进行编辑。“我使用myRunnable在不同类的多个位置创建新线程。”像本特建议的那样,在一个地方完成这一切也会减少代码重复。保持干燥。也许你想研究一下ExecutorService,并为这个特定的runnable配置一个。不过,你可能希望它是外部可观察、可配置和可控制的。在这种情况下,我会像ExecutorService一样使用线程池。我也是。线程不是完全的数据库连接,但有点类似。有了ExecutorService,如果需要真正调查那里发生了什么,你就有了一个良好的基础。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("Start: " + Thread.currentThread().getName());
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        Thread one = new Thread(myRunnable);
        Thread two = new Thread(myRunnable);
        one.start();
        two.start();

        List<Thread> threads = getThreadsFor(myRunnable);
        for (Thread thread : threads)
            System.out.println("Found: " + thread.getName());
    }

    private static List<Thread> getThreadsFor(Runnable myRunnable) throws Exception {
        Method getThreads = Thread.class.getDeclaredMethod("getThreads");
        Field target = Thread.class.getDeclaredField("target");
        target.setAccessible(true);
        getThreads.setAccessible(true);
        Thread[] threads = (Thread[]) getThreads.invoke(null);
        List<Thread> result = new ArrayList<Thread>();
        for (Thread thread : threads) {
            Object runnable = target.get(thread);
            if (runnable == myRunnable)
                result.add(thread);
        }
        return result;
    }
}