Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 何时使用Akka,何时不使用?_Java_Multithreading_Akka - Fatal编程技术网

Java 何时使用Akka,何时不使用?

Java 何时使用Akka,何时不使用?,java,multithreading,akka,Java,Multithreading,Akka,我现在的处境是,当我不使用演员的时候,我实际上通过使用演员使事情变得更加复杂。我需要在不阻塞主线程的情况下执行大量Http请求。因为这是并发性,我想尝试一些不同于锁的东西,所以我决定使用Akka。现在我的处境是,我怀疑两种方法之间的区别 方法一:在需要时创建新的参与者: public class Main { public void start() { ActorSystem system = ActorSystem.create(); // Creat

我现在的处境是,当我不使用演员的时候,我实际上通过使用演员使事情变得更加复杂。我需要在不阻塞主线程的情况下执行大量Http请求。因为这是并发性,我想尝试一些不同于锁的东西,所以我决定使用Akka。现在我的处境是,我怀疑两种方法之间的区别

方法一:在需要时创建新的参与者:

public class Main {
    public void start() {
        ActorSystem system = ActorSystem.create();

        // Create 5 Manager Actors (Currently the same Actor for all but this is different in actual practise)
        ActorRef managers = system.actorOf(new BroadcastPool(5).props(Props.create(Actor.class)));
        managers.tell(new Message(), ActorRef.noSender());
    }
}

public class Actor extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof Message) {
            ActorRef ref = getContext().actorOf(new SmallestMailboxPool(10).props(Props.create(Actor.class)));

            // Repeat the below 10 times
            ref.tell(new Message2(), getSelf());
        } else if (message instanceof Message2) {
            // Execute long running Http Request
        }
    }
}

public final class Message {
    public Message() {
    }
}

public final class Message2 {
    public Message2() {
    }
}
第二种方法是先创建一大批演员,希望足够:

public class Main {
    public void start() {
        ActorSystem system = ActorSystem.create();

        ActorRef actors = system.actorOf(new SmallestMailboxPool(100).props(Props.create(Actor.class)));
        ActorRef managers = system.actorOf(new BroadcastPool(5).props(Props.create(() -> new Manager(actors))));

        managers.tell(new Message(), ActorRef.noSender());
    }
}

public class Manager extends UntypedActor {

    private ActorRef actors;

    public Manager(ActorRef actors) {
        this.actors = actors;
    }

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof Message) {
            // Repeat 10 times
            actors.tell(new Message2(), getSelf());
        }
    }
}

public class Actor extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof Message2) {
            // Http request
        }
    }
}

public final class Message {
    public Message() {
    }
}

public final class Message2 {
    public Message2() {
    }
}
所以这两种方法都有上下两面。我们要确保它总是能够处理新的请求,这些请求永远不必等待。但是它留下了很多永远不会被使用的演员。另一方面,两个应用程序重用了参与者,但缺点是它可能没有足够的参与者,并且无法应付将来的某个时间,并且必须对消息进行排队

解决这一问题的最佳方法是什么?人们处理这一问题的最常见方式是什么


如果你认为不管有没有Akka,我都可以做得更好,请告诉我!我对阿克卡很陌生,很想了解更多

根据给定的信息,它看起来像是基于任务的并发的典型示例,而不是基于角色的并发。假设您有一个执行HTTP请求的方法。该方法获取给定的URL并返回一个对象,而不会导致共享内存上的任何数据竞争:

private static Page loadPage(String url) {
    // ...
}
您可以轻松地与执行器同时获取页面。有不同类型的执行器,例如,您可以使用具有固定线程数的执行器

public static void main(String... args) {
    ExecutorService executor = Executors.newFixedThreadPool(5);
    List<Future<Page>> futures = new ArrayList<>();
    // submit tasks
    for (String url : args) {
        futures.add(executor.submit(() -> loadPage(url)));
    }
    // access result of tasks (or wait until it is available)
    for (Future<Page> future : futures) {
        Page page = future.get();
        // ...
    }
    executor.shutdown();
}

不需要进一步的同步。Executor框架会解决这个问题。

我会使用混合方法:事先创建相对较小的参与者池,在需要时增加参与者池,但在连接太多时保持池的大小限制拒绝请求,以避免因内存不足而崩溃。

理想情况下提供实际代码。@djechlin,现在就可以了。为什么不使用?对于执行者来说,发出大量HTTP请求似乎是一个很好的例子,而对于参与者来说则不是。@djechlin我添加了一些代码。希望我这样做能让自己说得更清楚。@nosid那么你是说我应该放弃这种方法的整个参与者概念,而只使用执行者?所以基本上,在这方面,放弃参与者模型,使用普通的执行者服务?j.u.c.Future blocks来看看Java8 CompletableFuture或Scala的未来