如何编写可中断的方法 [英] How to write interruptable methods

查看:119
本文介绍了如何编写可中断的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法,在概念上看起来像:

I have a method which, conceptually, looks something like:

Object f(Object o1) {
    Object o2 = longProcess1(o1);
    Object o3 = longProcess2(o2);
    return longProcess3(o3);
}

流程本身也可能是复合的:

Where the processes themselves might also be compound:

Object longProcess1(Object o1) {
    Object o2 = longSubProcess1(o1);
    return longSubProcess2(o2);
}

依此类推,不同的流程可能位于不同的模块中。大多数进程都很长,因为它们的计算成本很高,而且不受IO限制。

And so forth, with the different processes potentially sitting in different modules. Most of the processes are long because they are computationally expensive, not IO-bound.

到目前为止一直很好,但现在我想要 f 作为一个整体可以中断。 推荐的Java方法是定期的使用 Thread.interrupted()检查中断的标志。它非常简单,但如果我需要将我的方法更改为以下内容,它很快就会变得很麻烦:

So far so good, but now I want f as a whole to be interruptable. The recommended Java way to do that is to periodically check for the interrupted flag with Thread.interrupted(). It's pretty straightforward, but it can quickly become cumbersome if I need to change my methods to something like:

Object f(Object o1) {
    Object o2 = longProcess1(o1);
    if (Thread.interrupted()) throw new InterruptedException();
    Object o3 = longProcess2(o2);
    if (Thread.interrupted()) throw new InterruptedException();
    return longProcess3(o3);
}

Object longProcess1(Object o1) {
    Object o2 = longSubProcess1(o1);
    if (Thread.interrupted()) throw new InterruptedException();
    return longSubProcess2(o2);
}

...

现在,我确实理解这样工作的理性 - 它允许我更好地控制何时抛出InterruptedException(例如),避免让对象处于不一致的状态 - 但是我很想知道是否存在更优雅的方式*

Now, I do understand the rational for working like that - it allows me to better control when the InterruptedException (for example) will be thrown, avoiding leaving objects in inconsistent states - but I am curious to know if there's a more elegant way of doing that*.

*在Java中,不是AspectJ,我认为这是非常合适的,但我坚持使用Java。 / p>

* In Java, not AspectJ, which I guess is very appropriate here but I'm stuck with Java.

推荐答案

您可以使用界面和动态代理:

You could use an interface and a Dynamic proxy:

public class Wrapper {
    public static <T> T wrap(Class<T> intf, final T impl) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        Object proxy = Proxy.newProxyInstance(cl, new Class<?>[] {intf},
                new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                if (Thread.interrupted()) {
                    throw new InterruptedException();
                }
                return method.invoke(impl, args);
            }
        });
        return intf.cast(proxy);
    }
}

interface Processes {
    Object longProcess1(Object o);
    ...
}

public class ProcessesImpl implement Processes {
    Processes self = Wrapper.wrap(Processes.class, this);

    public Object f(Object o1) {
        Object o2 = self.longProcess1(o1);
        Object o3 = self.longProcess2(o2);
        return self.longProcess3(o3);
    }

    public Object longProcess1(Object o1) {
        Object o2 = self.longSubProcess1(o1);
        return self.longSubProcess2(o2);
    }

    ....
}

这篇关于如何编写可中断的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆