在固定时间后中断线程,它是否必须抛出InterruptedException



我想在固定时间后中断线程。其他人也问了同样的问题,得票最多的人回答了(https://stackoverflow.com/a/2275596/1310503)给出了下面的解决方案,我稍微缩短了一下。

import java.util.Arrays;
import java.util.concurrent.*;
public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.invokeAll(Arrays.asList(new Task()), 2, TimeUnit.SECONDS);
        executor.shutdown();
    }
}
class Task implements Callable<String> {
    public String call() throws Exception {
        try {
            System.out.println("Started..");
            Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
            System.out.println("Finished!");
        } catch (InterruptedException e) {
            System.out.println("Terminated!");
        }
        return null;
    }
}

他们补充道:

sleep()不是必需的。它仅用于SSCCE/演示目的。只需在那里做你的长期任务,而不是睡觉()。

但是,如果用for (int i = 0; i < 5E8; i++) {}替换Thread.sleep(4000);,那么它就不会编译,因为空循环不会引发InterruptedException。为了使线程是可中断的,它需要抛出一个InterruptedException。

有没有任何方法可以使上面的代码与一般的长时间运行的任务而不是sleep()一起工作?

如果您希望您的操作是可中断的(即,在操作完成之前应该可以中断它),您需要使用其他可中断操作(Thread.sleep、InputStream.read,请阅读以获取更多信息),或者使用Thread.isIInterrupted.手动检查循环条件下的线程中断状态

您可以检查线程的中断状态,例如:

public static void main(String[] args) throws Exception {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.invokeAll(Arrays.asList(new Task()), 2, TimeUnit.SECONDS);
    executor.shutdown();
}
static class Task implements Callable<String> {
    public String call() throws Exception {
        System.out.println("Started..");
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Interrupted!");
                return null;
            }
        }
        System.out.println("Finished!");
        return null;
    }
}

您误解了。

"…要使线程可中断,它需要抛出InterruptedException"根本不是真的。catch块之所以存在,只是因为Thread.sleep()方法抛出InterruptedException。如果您没有使用sleep(或任何其他可以抛出InterruptedException的代码),那么您就不需要catch块。

如果替换sleep,则所有代码都不会抛出InterruptedException。您应该删除InterruptedException:的try-catch

public String call() {
    System.out.println("Started..");
    for (int i = 0; i < 5E8; i++) {}
    System.out.println("Finished!");
    return null;
} 

相关内容

  • 没有找到相关文章

最新更新