java - 实现共享计算的 Future 接口(interface)

标签 java multithreading future

我正在实现 Future<Collection<Integer>>接口(interface),以便在应用程序中的所有线程之间共享一些批量计算的结果。

事实上,我只想放置一个实现 Future<Collection<Integer>> 的类的实例。到 ApplicationScope 对象中,以便任何其他需要结果的线程只需请求 Future来自object并调用方法get()其上,因此使用由另一个线程执行的计算。

我的问题是关于实现cancel方法。现在,我会写这样的东西:

public class CustomerFutureImpl implements Future<Collection<Integer>>{

    private Thread computationThread;
    private boolean started;
    private boolean cancelled;
    private Collection<Integer> computationResult;

    private boolean cancel(boolean mayInterruptIfRunning){
        if( computationResult != null )
            return false;
        if( !started ){
            cancelled = true;
            return true;
        } else {
            if(mayInterruptIfRunning)
                 computationThread.interrupt();
        }
    }

    //The rest of the methods
}

但是方法实现不满足 Future 的文档因为我们需要抛出 CancellationException在任何等待结果的线程中(已调用 get() 方法)。

我是否应该添加另一个字段,例如 private Collection<Thread> waitingForTheResultThreads;然后中断 Collection 中的每个线程,捕获中断异常,然后 throw new CancellationException()

问题是这样的解决方案对我来说似乎有点奇怪......对此不确定。

最佳答案

一般来说,您应该完全避免直接实现 Future。并发代码很难正确执行,分布式执行框架(尤其是 ExecutorService )将提供 Future 实例来引用您关心的工作单元。

您可能已经知道并且正在有意创建一个新的类似服务,但我认为重要的是要指出,对于绝大多数用例,您不需要定义自己的 Future实现。

您可能想查看 Guava 提供的并发工具,特别是 ListenableFuture ,它是 Future 的子接口(interface),提供附加功能。


假设您确实想要定义自定义 Future 类型,请使用 Guava 的 AbstractFuture 实现作为起点,这样您就不必重新发明遇到的复杂细节。

对于您的具体问题,如果您查看 implementation of AbstractFuture.get() ,您会发现它是通过 while 循环实现的,该循环查找 value 变为非空,此时它调用 getDoneValue() ,它返回该值或引发一个CancellationException。因此,本质上,每个阻塞调用 Future.get() 的线程都会经常轮询 Future.value 字段,如果检测到 CancellationException 已被取消,则会引发 Future。无需跟踪 Collection<Thread> 或任何类似的内容,因为每个线程都可以独立检查 Future 的状态,并根据需要返回或抛出。

关于java - 实现共享计算的 Future 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32841528/

相关文章:

java - 了解java的 native 线程和jvm

C++11 async - 最佳线程数的管理是自动的吗?

java - Callable 执行期间出现异常

java - 在 MIDI 音序器中控制音量的方法是什么?

java - 获取线程的堆栈跟踪对其性能有影响吗?

java - 在 hdfs 上将 csv 文件转换为另一种 csv 格式

java - 如何在简单的现金存取程序中处理多线程

scala - 如何在 Actor 的接收方法中使用 Future 来处理容错?

java - 如何将其他属性引用到 log4j2 yaml 配置中?

java - 自定义 MapReduce 输入格式 - 找不到构造函数