如何用以后中断线程,希望通过将来发出的中断来执行某些任务

时间:2014-02-05 19:24:19

标签: java multithreading future cancellation interrupted-exception

我是Java的未来和多线程的新手。我有一个简单的问题,结果很复杂,我有许多线程(都有开放的会话),这些线程是无限开放的。每当一个线程抛出自定义异常(会话超时异常)时,我必须中断所有线程并正常关闭所有会话。我所做的是我存储线程返回的未来对象(在ArrayList中)并循环遍历它,并在一个线程抛出异常时为所有人发出future.cancel。

private static void futureCancel()
{
        for(int i=0;i<numberStreams;i++)
        {
            Future<String> future=futureList.get(i);
            try{
                future.cancel(true);
                future.get();
            }
            catch(InterruptedException e)
            {
                System.out.println("In interrupted block!");
            } catch (ExecutionException e) {
                e.printStackTrace();
            }       
        }
        return;
    }

这里的问题是我不能在我的线程代码中添加InterruptedException,因为一些需求问题以及会话另一端的工作方式。如果我从我的callable中抛出InterruptedException,它就不会到达上面指定的catch块。如果我在我的线程中添加sleep(可以测试)并处理InterruptedException,它会在future.cancel发出后立即进入该块。我做错了什么?

2 个答案:

答案 0 :(得分:1)

  

如果我从我的callable中抛出InterruptedException,它就不会到达上面指定的catch块。

不会。 InterruptedException周围的future.get()捕获块是指调用获取的线程被中断 - 而不是Callable

如果Callable被中断并抛出InterruptedException,那么当您致电get()时,它将会输入ExecutionExceptione.getCause()应为InterruptedException }。

答案 1 :(得分:1)

Futuer#cancel(boolean) javadoc

  

如果任务已经完成,此尝试将失败   被取消,或因某些其他原因无法取消。如果   成功,并且当调用取消时,此任务尚未启动   任务永远不应该运行。如果任务已经开始,那么   mayInterruptIfRunning参数确定是否为该线程   执行此任务应该被中断,试图阻止   任务。

因此,ExecutorService尚未执行Runnable / Callable并且可以将其从队列中移除,或者它已经ExecutorService必须调用Thread#interrupt()并且您的Runnable / Callable代码必须处理它。

通过Future接口没有其他方法来中断线程。如果您的Runnable无法处理中断,那么可能会发生许多事情。如果发生InterruptedException,则会冒出ExecutorService并将其包含在ExecutionException中,该Future#get()将从InterruptedException引发。如果执行Runnable的主题中没有Runnable,则Runnable将继续畅通无阻。

您应该考虑更改{{1}}来处理中断。