• Scala的Actor模式 & Akka框架


    今天学Spark的时候,看到Scala的actor模式是一个加分点。所以搜了一下,看了。主要参考下面两篇文章,还没有实验,有些地方领会的不深刻:

    http://nxlhero.blog.51cto.com/962631/1666250

    十分钟理解Actor模式

    Actor模式是一种并发模型,与另一种模型共享内存完全相反,Actor模型share nothing。所有的线程(或进程)通过消息传递的方式进行合作,这些线程(或进程)称为Actor。共享内存更适合单机多核的并发编程,而且共享带来的问题很多,编程也困难。随着多核时代和分布式系统的到来,共享模型已经不太适合并发编程,因此几十年前就已经出现的Actor模型又重新受到了人们的重视。MapReduce就是一种典型的Actor模式,而在语言级对Actor支持的编程语言Erlang又重新火了起来,Scala也提供了Actor,但是并不是在语言层面支持,Java也有第三方的Actor包,Go语言channel机制也是一种类Actor模型。

    多线程/分布式编程-Actor模型


    到了分布式系统时代,工厂已经用流水线了,每个人都有明确分工,这就是Actor模式。每个线程都是一个Actor,这些Actor不共享任何内存,所有的数据都是通过消息传递的方式进行的。

     

    用scala实现,下面是工程的结构:

    这是它们传递的消息,有一些指令,剩下的都是Int数据:

    一个Actor的代码结构一般是下面这种结构,不停的接受消息并处理,没有消息就等待:

     组装者代码:

    分发者代码:

     加工者代码:

    主线程代码:

    这个代码实现的效果与前面用Java实现的是一样的,但是各个线程没有共享内存,也没有锁,这样开发起来容易,而且更适合分布式编程,因为分布式编程本身就不适合共享内存。

    Scala的Actor不能原生的支持分布式,但是Erlang可以,使用Erlang的Actor,分布式编程就和本地编程基本一样。但是Erlang的语法难懂,而且没有变量,几乎所有需要使用循环的地方都得用递归。

    但是,没有找到附件。算了。

    还有这篇文章:

    http://www.cnblogs.com/shiyangxt/archive/2011/07/30/2121663.html

    Scala.Actor实践心得与设计思想

    Scala的Actor

    可谓这门语言的一个亮点,函数式编程核心价值在于多核编程,所以就打算说说这个Actor,总结一下学习心得。

    Actor是一种基于事件的轻量级线程,在以前的并发模型中,我们需要关注共享的数据结构,而使用Actor则需要

    关注操作数据的代码结构,因为减少了数据的共享。Actor的主要能力来源于消息传递,而不是采用阻塞调用的处理形式。

    如果创建直接或间接扩展 Actor的类,要确保对对象的所有调用都通过消息传递进行

    以消息传递为核心的设计:使用Actor的actor方法,使用不可变对象,不考虑数据共享问题,以消息传递为设计核心。

    import actors._, Actor._
    
    object SendMessageStyle {
    
      def main(args: Array[String]): Unit = {
        val caller = self
        val accumulator = actor {
          var continue = true
          var sum = 0
          loopWhile(continue) {
            reactWithin(500) {
              case number: Int => sum += number
              case TIMEOUT =>
                continue = false
                caller ! sum
            }
          }
        }
        accumulator ! 1
        accumulator ! 2
        accumulator ! 3
        receiveWithin(1000) {
          case result => println("Total is " + result)
        }
      }
    }
    View Code

    中间用Java调用Scala函数的代码,略。

    测试结果:当使用Receive方法接收消息时,由于Receive会在结束任务前一直持有线程,而Scala在后台默认只给Receive

    方法启动256个线程,我的程序又是顺序的发消息,而且不是临时接收器(只处理一次消息),所以Receive在这种情况下,

    只有255个并发。React接收器由于不需要长期持有线程,空闲即释放线程。所以React在本程序中可以跑20w的并发,如果

    简单优化一下JVM,就可以达到100w的并发量。默认React接收器后台会调用4个线程组成的线程池。如果修改程序让每个数

    组元素给后一位数组元素并发的发消息,那么在不阻塞线程的情况下,Receive方法也可以达到和React一样的并发量。因为

    这个测试程序是顺序发送消息,所以就没有设置超时,如果是并发环境,建议加上超时,避免线程阻塞。

    100w,真的假的。。

    前些天看到Scala正在努力支持.net平台,不过我觉得.net平台有F#,所以对于.net程序员来说Scala提供不了什么

    附加价值。如果非要找出来这样做的优点的话,就是Scala可以同时支持两个主流平台。

    再看一下 Akka框架:

    http://blog.csdn.net/jmppok/article/details/17264495

    Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java 和 Scala 的 Actor 模型应用。

  • 相关阅读:
    面试题|Docker的优缺点
    【华为出品】物联网全栈开发实战营来啦!送海思双目开发板
    Nginx实战|Nginx健康检查
    Linux中几个正则表达式的用法
    盘点提高国内访问 Github 的速度的 9 种方案
    一行代码如何隐藏 Linux 进程?
    (二)类加载机制与反射:类加载器
    (一)类加载机制与反射:类的加载,连接和初始化
    (八)多线程:线程相关类
    (七)多线程:线程池
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6225956.html
Copyright © 2020-2023  润新知