akka学习教程(十) agent

akka系列文章目录

我们知道在JDK中,编写多线程代码时要谨慎处理临界区的数据,可以加锁或者使用JDK自带的CAS库:atomic相关包。

那么在akka中怎么处理呢?akka给我们提供了一个agent。可以使用agent来实现共享变量的安全处理。

下面示例为10个actor并发累加countAgent变量。每个累加10000次。如果正确的话,最终结果应该是10W。

package akka;

import akka.actor.*;
import akka.agent.Agent;
import akka.dispatch.ExecutionContexts;
import akka.dispatch.Futures;
import akka.dispatch.Mapper;
import akka.dispatch.OnComplete;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import com.typesafe.config.ConfigFactory;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by liubenlong on 2017/1/12.
 */
public class AgentTest extends UntypedActor {

    private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);

    @Override
    public void onReceive(Object o) throws Throwable {
        if(o instanceof Integer){
            for(int i = 0 ; i < 10000 ; i ++){
                Future<Integer> future = countAgent.alter(new Mapper<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer parameter) {
                        return parameter + 1;
                    }
                });
                queue.add(future);
            }

            getContext().stop(getSelf());//完成任务,关闭自己
        }else{
            unhandled(o);
        }
    }


    public static CountDownLatch latch = new CountDownLatch(10);
    public static Agent<Integer> countAgent = Agent.create(0, ExecutionContexts.global());
    public static ConcurrentLinkedQueue<Future<Integer>> queue = new ConcurrentLinkedQueue<>();

    public static void main(String [] args) throws InterruptedException, TimeoutException {
        ActorSystem system = ActorSystem.create("inbox", ConfigFactory.load("akka.conf"));

        ActorRef[] actorRefs = new ActorRef[10];
        for(int i = 0 ; i < 10 ; i ++){
            actorRefs[i] = system.actorOf(Props.create(AgentTest.class), "AgentTest" + i);
        }

        Inbox inbox = Inbox.create(system);
        for (ActorRef ref : actorRefs) {
            inbox.send(ref, 1);
            inbox.watch(ref);
        }

        System.out.println("countAgent 1:" + countAgent.get());


        /*
         * 这里本来想用JDK里的AtomicInteger, 但是不行,不适用于这里的actor
         */


        //等待所有actor执行完毕
        int closeCount = 0;
        while(true){
            Object o = inbox.receive(Duration.create(1, TimeUnit.SECONDS));
            if(o instanceof Terminated){
                closeCount ++;
                if(closeCount == actorRefs.length){
                    break;
                }
            }else{
                System.out.println("o:" + o);
            }
        }

        System.out.println("countAgent 2:" + countAgent.get());

        //等待所有累加线程完成
        Futures.sequence(queue, system.dispatcher()).onComplete(new OnComplete<Iterable<Integer>>() {
            @Override
            public void onComplete(Throwable throwable, Iterable<Integer> integers) throws Throwable {
                System.out.println("countAgent 3:" + countAgent.get());
                system.shutdown();
            }
        }, system.dispatcher());

    }
}

运行结果:

countAgent 1:0
countAgent 2:10
countAgent 3:100000

参考资料

内容简介 本书将尝试帮助入门级、中级以及高级读者理解基本的分布式计算概念,并且展示 如何使用 Akka 来构建具备高容错性、可以横向扩展的分布式网络应用程序。Akka 是一 个强大的工具集,提供了很多选项,可以对在本地机器上处理或网络远程机器上处理的 某项工作进行抽象封装,使之对开发者不可见。本书将介绍各种概念,帮助读者理解 网络上各系统进行交互的困难之处,并介绍如何使用 Akka 提供的解决方案来解决这些 问题。 作者简介 Jason Goodwin 是一个基本上通过自学成才的开发者。他颇具企业家精神,在学校 学习商学。不过他从 15 岁起就开始学习编程,并且一直对技术保持着浓厚的兴趣。这对 他的职业生涯产生了重要的影响,从商学转向了软件开发。现在他主要从事大规模分布 式系统的开发。在业余时间,他喜欢自己原创电子音乐。 他在 mDialog 公司第一次接触到 Akka 项目。mDialog 是一家使用 Scala/Akka 的公司, 为主流出版商提供视频广告插入软件。这家公司最终被 Google 收购。他同时还是一名很 有影响力的“技术控”,将 Akka 引入加拿大一家主要的电信公司,帮助该公司为客户提 供容错性更高、响应更及时的软件。除此之 外,他还为该公司中的一些团队教授 Akka、 函数式以及并发编程等知识。 目录 第 1 章 初识 Actor:Akka 工具集以及 Actor 模型的介绍。 第 2 章 Actor 与并发:响应式编程。Actor 与 Future 的使用。 第 3 章 传递消息:消息传递模式。 第 4 章 Actor 的生命周期—处理状态与错误:Actor 生命周期、监督机制、Stash/ Unstash、Become/Unbecome 以及有限自动机。 第 5 章 纵向扩展:并发编程、Router Group/Pool、Dispatcher、阻塞 I/O 的处理以 及 API。 第 6 章 横向扩展—集群化:集群、CAP 理论以及 Akka Cluster。 第 7 章 处理邮箱问题:加大邮箱负载、不同邮箱的选择、熔断机制。 第 8 章 测试与设计:行为说明、领域驱动设计以及 Akka Testkit。 第 9 章 尾声:其他 Akka 特性。下一步需要学习的知识。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐崇拜234

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值