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

时间:2012-04-05 15:34:36

标签: java concurrency timeout

我想在一段固定的时间后中断一个线程。其他人问了同样的问题,最高投票的答案(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 /演示目的。只是在那里做长期运行的任务而不是睡觉()。

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

是否有任何方法可以使上述代码与常规的长期运行任务一起使用而不是sleep()

4 个答案:

答案 0 :(得分:2)

你误会了。

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

答案 1 :(得分:2)

如果您希望操作可中断(即应该可以在完成之前中断它),您需要使用其他可中断操作(Thread.sleep,InputStream.read,read for more info)或手动检查使用Thread.isInterrupted在循环条件中的线程中断状态。

答案 2 :(得分:2)

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

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

答案 3 :(得分:-1)

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

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