Akka Future线程永远不会发布

时间:2016-01-18 15:36:46

标签: java multithreading akka

我正在尝试并行执行一些繁重的计算。为此,我使用Akka(在Java中)。

而不是定义actor,我将计算包装到Future中,如文档所示。

计算是正确并行执行的,但问题是为Future<>打开的线程永远不会关闭,在某些时候我会遇到错误:OutOfMemory: unable to create new native thread

我的代码结构如下所示:

public void compute(){
    for(Attribute attribute : attributes){
        computeAttribute(attribute);
    }
}

private void computeAttribute(Attribute attribute){
    ActorSystem system = ActorSystem.create("System");
    int nb = findNumberOfIterations(attribute);

    List<Future<AttributeResult>> answers = new ArrayList<>();

    // Computation to be performed in parallel
    for (int i = 0; i < nb; i++) {
        // MasterCaller contains the heavy computation logic
        Future<AttributeResult> f = Futures.future(new MasterCaller(attribute, i), system.dispatcher());
        answers.add(f);
    }

    Future<Iterable<AttributeResult>> futures = Futures.sequence(answers, system.dispatcher());

    Future<AttributeResult> futureTotal = futures.map(new MasterMapper(), system.dispatcher());

    try {
        // Additional processing step after all resulted have been computed
        AttributeResult value = Await.result(futureTotal, Duration.create(1, TimeUnit.SECONDS));
        postProcess(value, attribute);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

让我们说每次调用computeAttribute()时会创建大约10个线程。然后,如果attributes列表中有1000个元素,代码将继续创建10 000个活动线程!

我真的很感激得到一些帮助,因为这个问题使得Akka的使用和并行计算变得不可能。

1 个答案:

答案 0 :(得分:5)

问题在于,您为computeAttribute的每次调用创建了一个新的ActorSystem,并且您永远不会将其关闭。由于您没有在Akka中使用任何内容,我建议您使用computeAttribute - 方法将scala.concurrent.ExecutionContext作为参数,然后您可以通过{{1传递自己创建的任何一个或ExecutionContext.fromExecutorService(您仍然需要在适当的时间点关闭它们)或传递ExecutionContext.fromExecutor