Akka中的Future和Agent

询问模式:Actor中的Future

与同步方法不同,在发送异步消息后,接受消息的Actor可能根本来不及处理你的消息,调用方就已经返回了,和Future模式不同的是,在传统的异步调用中,我们进行的是函数调用,但在这里,我们发送了一条消息。

printer Actor

public class Printer extends UntypedAbstractActor {
    @Override
    public void onReceive(Object message) throws Throwable {
        if(message instanceof Integer){
            System.out.println("Printer:"+message);
        }else {
            unhandled(message);
        }
    }
}

Woker Actor

public class Worker extends UntypedAbstractActor {
    @Override
    public void onReceive(Object message) throws Throwable {
        if (message instanceof Integer) {
            Thread.sleep(1000);
            int i = Integer.parseInt(message.toString());
            getSender().tell(i*i, getSelf());
        } else {
            unhandled(message);
        }

    }

    public static void main(String[] args) throws TimeoutException, InterruptedException {
        ActorSystem system=ActorSystem.create("askdemo");
        ActorRef a=system.actorOf(Props.create(Worker.class),"worker");
        ActorRef b=system.actorOf(Props.create(Printer.class),"printer");

        Future<Object> f= Patterns.ask(a,5,1000);
        int re= (int) Await.result(f,Duration.create(6,TimeUnit.SECONDS));
        System.out.println("result:"+re);

        Future<Object> future1 = Patterns.ask(a, 8, 1000);
        Patterns.pipe(future1, system.dispatcher()).to(b);


        a.tell(PoisonPill.getInstance(), ActorRef.noSender());

    }
}

在这里插入图片描述

多个Actor同时修改数据:Agent

在Akka中,使用一种叫做Agent的组件来实现多个Actor访问同一个变量。当一个Actor希望改变Agent的值时,它会向Agent下发一个动作(action)。当多个Actor同时改变Agent时,这些action将会在ExecutionContext中被并发调度执行。在任意时刻,一个Agent最多只能执行一个action,对于某一个线程来说,它执行action的顺序与它的发生顺序一致,但对于不同线程来说,这些action可能会交织在一起。
Agent的修改可以使用两种方式:send和alter,区别就在于send方法没有返回值,而alter方法会返回一个Future对象。


public class CounterActor extends UntypedAbstractActor {

    public class AgentDemo{
        public static Agent<Integer> counterAgent=Agent.create(0, ExecutionContexts.global());
        static ConcurrentLinkedQueue<Future<Integer>> futures=new ConcurrentLinkedQueue<>();
    }

    Mapper addMapper=new Mapper<Integer,Integer>(){
        @Override
        public Integer apply(Integer parameter) {
            return parameter+1;
        }
    };
    @Override
    public void onReceive(Object message) throws Throwable {
        if(message instanceof Integer){
            for (int i = 0; i < 10000; i++) {
                Future<Integer> f=AgentDemo.counterAgent.alter(addMapper);
                AgentDemo.futures.add(f);
            }
            getContext().stop(getSelf());
        }else{
            unhandled(message);
        }
    }

    public static void main(String[] args) {
        ActorSystem system=ActorSystem.create();
        ActorRef[] counter=new ActorRef[10];
        for (int i = 0; i <counter.length ; i++) {
            counter[i]=system.actorOf(Props.create(CounterActor.class),"counter_"+i);
        }
        Inbox inbox =Inbox.create(system);
        for (int i = 0; i < counter.length; i++) {
            inbox.send(counter[i],1);
            inbox.watch(counter[i]);
        }
        int closeCount=0;

        while (true){
            Object msg=inbox.receive(Duration.create(1,TimeUnit.SECONDS));
            if(msg instanceof Terminated){
                closeCount++;
                if(closeCount==counter.length){
                    break;;
                }
            }else{
                System.out.println(msg);
            }
        }

        //等待所有的累加线程完成
        Futures.sequence(futures,system.dispatcher()).onComplete(new OnComplete<Iterable<Object>>() {
            @Override
            public void onComplete(Throwable failure, Iterable<Object> success) throws Throwable {
                System.out.println("counterAgent="+counterAgent.get());
                system.shutdown();
            }
        },system.dispatcher());
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值