2

我有多个子线程实例,它们已启动并且应该继续执行,直到应用程序退出。

我有扩展 Task 的类,我将线程创建为

new Thread(object of the class).start();

所有线程都应在关闭主要阶段时终止。

primaryStage.onCloseOperation(){...}
4

3 回答 3

3

我会从一开始就明确地管理你的线程。特别是,在您的父类中有一个线程池,如下所示:

ExecutionService exec = Executors.newCachedExecutionService();

然后,如果您的任务旨在继续运行(而不是定期安排),则对您的任务进行编码以响应中断,如下所示:

while(!Thread.currentThread().isInterrupted()){
    do stuff;
}

这将使任务运行直到被中断。在这种情况下,重要的是永远不要忽略InterruptedException,因为当它们被抛出时InterruptedException设置为 false 。isInterrupted当你看到一个InterruptedException

}catch(InterruptedException e){
    Thread.currentThread().interrupt();
    return;
}

然后,您可以像这样开始您的子任务:

for(task : tasks){
    exec.execute(task);
}

现在,当您的父任务完成时,您可以简单地调用:

exec.shutdownNow();

停止您的子任务。如果您的子任务使用Thread.currentThread().isInterrupted(),则必须使用shutdownNow()shutdown()仅当您想等待任务自行停止时才有效)。

于 2013-09-12T06:00:35.757 回答
1

您应该考虑使用ThreadGroup对所有线程进行分组,然后控制它们的行为。Java 5 在 java.lang.management 中添加了 ThreadInfo 和 ThreadMXBean 类来获取状态信息。

这是使用此处提供的教程http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups的示例示例:

获取所有线程的列表

ThreadGroup 上的另一个 enumerate() 方法列出了该组的线程。使用真正的第二个参数,它将递归遍历组以使用 Thread 对象填充给定数组。从根 ThreadGroup 开始,您将获得 JVM 中所有线程的列表。

这里的问题与列出线程组的问题相同。如果传递给 enumerate() 的数组太小,一些线程可能会从返回的数组中默默地删除。因此,您需要猜测数组的大小,调用 enumerate(),检查返回值,如果数组已满,再试一次。要获得一个好的开始猜测,请查看 java.lang.management 包。那里的 ManagementFactory 类返回一个 ThreadMXBean,它的 getThreadCount() 方法返回 JVM 中的线程总数。当然,这可能会在稍后改变,但这是一个很好的初步猜测。

Thread[] getAllThreads( ) {
    final ThreadGroup root = getRootThreadGroup( );
    final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
    int nAlloc = thbean.getThreadCount( );
    int n = 0;
    Thread[] threads;
    do {
        nAlloc *= 2;
        threads = new Thread[ nAlloc ];
        n = root.enumerate( threads, true );
    } while ( n == nAlloc );
    return java.util.Arrays.copyOf( threads, n );
}
于 2013-09-12T05:50:34.690 回答
0

创建一个ExecutorService其中有一个ThreadFactory创建守护线程。

例如 :

ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
     @Override
     public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setDaemon(true);
        return thread;
     }
});

@Enno 已经说过其余的如何使用它。

谢谢恩诺:)

于 2013-09-12T15:27:06.683 回答