Java - 获取线程状态

时间:2014-01-20 06:53:12

标签: java multithreading threadpool

我使用ThreadPoolExecutor来运行线程。

ExecutorService executorService = Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyRunnable());

基于某些条件,我需要终止长时间运行的线程并再次启动相同的线程实例(对于某些清理操作)。

由于我有一个未来的线程对象,我可以轻松检查它是否仍在运行。

 future.isDone()

如果它正在运行,我可以使用

发送中断信号
 future.cancel(true);

MyRunnable类中,处理中断信号。但是在循环开始时检查这个条件。

问题是future.isDone()在发送中断信号后立即返回true。但我需要等到线程实例真正完成。

有没有办法检查线程是否真的在运行/完成?

2 个答案:

答案 0 :(得分:1)

Apidoc还提到future.isDone()如果future.cancel()被调用则返回true,即它并不总是告诉你任务是否已经完成。 要检查任务是否已完成,您需要访问Runnable,然后您可以检查任务是否已完成或等待任务完成。
将下面的代码与它下面显示的输出进行比较,我想这会让您了解您的选择:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Q21227864 {

public static void main(String[] args) {

    ExecutorService executorService = Executors.newCachedThreadPool();
    Future<?> future = executorService.submit(new MyRunnable());
    sleep(100L);
    future.cancel(true);
    System.out.println("Future done: " + future.isDone());
    sleep(100L);
    future.cancel(true);
    System.out.println("Future done: " + future.isDone());
    sleep(500L);
    System.out.println("Future done: " + future.isDone());

    System.out.println("---");

    MyRunnable mr = new MyRunnable();
    future = executorService.submit(mr);
    sleep(100L);
    future.cancel(true);
    System.out.println("Runnable done: " + mr.isDone());
    sleep(100L);
    System.out.println("Runnable done: " + mr.isDone());
    mr.waitForCleanup();
    System.out.println("Runnable done: " + mr.isDone());

    executorService.shutdownNow();
}

public static void sleep(long timeMs) { 
    try { Thread.sleep(timeMs); } catch (Exception ignored) {}
}

static class MyRunnable implements Runnable {

    final CountDownLatch completed = new CountDownLatch(1);

    public void run() {

        try {
            System.out.println("Sleeping loop");
            Thread.sleep(1000L);
            System.out.println("Sleeping loop done");
        } catch (Exception e) {
            System.out.println("Stopped loop: " + e);
        }
        try {
            System.out.println("Sleeping cleanup");
            Thread.sleep(300L);
            System.out.println("Sleeping cleanup done");
        } catch (Exception e) {
            System.out.println("Stopped cleanup: " + e);
        }
        completed.countDown();
    }

    public boolean isDone() {
        return (completed.getCount() == 0);
    }

    public void waitForCleanup() {
        try { completed.await(); } catch (Exception ignored) {}
    }

}

}

输出:

Sleeping loop
Future done: true
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Future done: true
Sleeping cleanup done
Future done: true
---
Sleeping loop
Runnable done: false
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Runnable done: false
Sleeping cleanup done
Runnable done: true

答案 1 :(得分:0)

我不认为future.isDone()会在发送中断信号后立即返回true。所有ThreadPoolExecutor任务都通过FutureTask.run()方法执行

public class FutureTask<V> implements RunnableFuture<V> {
    ...    
    public boolean isDone() {
        return state != NEW;
    }

    public void run() {
    ...
            try {
                Callable<V> c = callable;
                if (c != null && state == NEW) {
                    V result;
                    boolean ran;
                    try {
                        result = c.call();   <-- this invokes your code
                        ran = true;
                    } catch (Throwable ex) {
                        result = null;       <-- if you threw InterruptedException
                        ran = false;
                        setException(ex);    <-- state changes here
                    }
                    if (ran)
                        set(result);         <-- if your code simply returns then state changes here
                }
    ...