本文主要讲解Scala的并发(并行)编程,那么为何题目概称geotrellis使用(六)呢,主要由于本系列讲解如何使用Geotrellis,具体前几篇博文已经介绍过了。我以为干任何一件事情基础很重要,就像当年参加高考或者各类考试同样,老师都会强调基础,这是颇有道理的。使用Geotrellis框架的基础就是Scala和Spark,因此本篇文章先来介绍一下Scala编程语言,一样要想搞明白Scala并发(并行)编程,Scala基础也很重要,没有Scala语言基础就谈不上Scala并发编程也就更谈不上使用Geotrellis或者Spark,本文先简单介绍一下Scala基础知识,这方面的书籍或者文章不少,你们能够网上找一下。html
1、Scala基础 java
关于Scala基础最主要的就是模式匹配,这造就了整个Scala语言灵活方便的特色,通俗的说模式匹配就是其余语言中的switch case,可是其实功能要远远复杂的多,涉及到样本类(case class)、unapply函数等具体网上有不少介绍。其次还有强大的for表达式、偏函数、隐式转换等,下面主要为你们介绍Scala并发(并行)编程。编程
2、SBT简介 并发
使用Scala语言编程,最好使用SBT框架,能够自动帮你完成包管理等,至关于java中的maven,下面先简单介绍一下SBT基础。app
首先安装SBT,很简单,只须要下载安装包便可(http://www.scala-sbt.org/release/docs/Installing-sbt-on-Windows.html),具体安装过程以及配置等,你们也能够在网上找的到。安装完成以后,在IDEA中安装sbt插件,而后选择建立SBT项目,与普通Scala语言最主要的不一样是会建立一个build.sbt文件,这个文件主要记录的就是项目的依赖等,要添加依赖就能够添加以下两行代码:框架
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.4.4" resolvers += "Akka Snapshot Repository" at "http://repo.akka.io/snapshots/"
其实build.sbt文件是一个被SBT直接管理的scala源文件,里面的语句均要符合Scala语法,其中libraryDependencies和resolvers 是定义好的Key,+= % at等都是写好的方法。libraryDependencies是存储系统依赖的Key,该语句添加了一个ModuleID对象,"com.typesafe.akka"为groupID,"akka-actor_2.11"为artifactID,2.4.4"为revision,%方法最终就建立了一个ModuleID对象,此处须要注意_2.11表示当前的Scala版本。resolvers表示系统如何可以找到上面的libraryDependencies,at 方法经过两个字符串建立了一个 Resolver 对象,前者为名称,后者为地址。通常lib的官网中均会有写明本身的上述语句供使用者方便添加本身lib依赖。maven
3、并发编程 tcp
下面为你们介绍如何使用Scala进行并发编程。编程语言
一、原生支持ide
Scala语言原生支持并发编程,只须要使类继承scala.actors.Actor便可,复写父类的act方法,也能够直接创建一个匿名类,直接使用actor{}便可,其中receive是一个偏函数,用于接收并处理其余Actor发送的消息,这里就用到了模式匹配,能够根据不一样的消息类型进行不一样的处理,至关于路由。
1 object ActorTest2 extends App { 2 val actor_a: Actor = actor{ 3 while (true){ 4 receive { 5 case msg => println("actor_a " + msg) 6 } 7 } 8 } 9 10 val actor_b = actor{ 11 while (true){ 12 receive { 13 case msg => { 14 println("actor_b " + msg) 15 actor_a ! "b ---- >>> a" 16 sender ! "receive " + msg 17 } 18 } 19 } 20 } 21 22 actor_a ! "wsf" 23 actor_b ! Math.PI 24 }
上面的代码定义了两个Actor对象actor_a,actor_b,采用此种方式Actor会自动start,而后在主线程中各向每一个Actor发送了一条信息,Actor接收到信息后进行简单的打印操做。因为Scala已经废弃了此种方式来进行并发编程,在这里也只是简单介绍,下面咱们来看一下如何经过使用akka来进行并发编程。
二、akka
akka是一个简单易用的Scala并发编程框架(网址:http://akka.io/),其宗旨就是"Build powerful concurrent & distributed applications more easily."。引入akka只须要在build.sbt文件中添加在SBT操做一节中介绍的代码便可,可是要根据本身的Scala版本以及要使用的akka版本进行修改。添加完以后IDEA会自动去下载akka的actor包。其使用基本与原生actor相同,一样建立一个类继承akka.actor.Actor,复写其receive方法。其代码以下:
1 class MyActor extends Actor{ 2 override def receive={ 3 case message: String=> println(message) 4 case _ => unhandled() 5 } 6 }
与原生Actor不一样的是akka为其Actor加入了path的概念,即每一个Actor都有一个绝对路径,这样系统首先要建立一个system,而后在system建立其下的Actor,代码以下:
val system = ActorSystem("akkatest")
val actor = system.actorOf(Props(classOf[wsf.akkascala.MyActor]), "akkaactor")
其中ActorSystem("akkatest")即建立一个akka的system,用于管理Actor,第二句就是在system中建立一个上面MyActor实例。经过打印actor.path能够获得akka://akkatest/user/akkaactor,能够看出该Actor确实是在system之下,其中user表示是用户自定义Actor。
Actor实例建立以后无需start,会自动启动,可使用actor ! "hello actor"语句来向actor发送消息,MyActor的receive方法接收到该语句以后进行模式匹配,若是可以匹配上就行进行相应的处理。
因为Actor具备了路径,其也就可以建立属于本身的Actor实例,只须要在当前Actor类中添加以下代码:
val otherActor = context.actorOf(Props(classOf[OtherActor]), "otheractor")
其中OtherActor是定义好的另外一个Actor,打印otherActor.path能够获得以下效果:akka://akkatest/user/akkaactor/otheractor,这就代表确实在MyActor中建立了一个子Actor。MyActor就能够管理OtherActor的实例。
以上介绍了akka的并发编程,其并行编程要稍做修改。
首先创建一个RemoteActor项目,将build.sbt中项目的引用改成libraryDependencies ++= Seq("com.typesafe.akka" % "akka-actor_2.11" % "2.4.4","com.typesafe.akka" % "akka-remote_2.11" % "2.4.4"),能够看出相比普通Actor项目只是添加了一个akka-remote引用。而后新建一个RemoteActor类一样继承自Actor,与普通Actor毫无区别。而后建立一个主类启动该Actor。惟一须要注意的就是要在resources文件夹中新建一个application.conf文件,该文件是系统的配置文件,里面添加以下代码:
1 akka { 2 loglevel = "INFO" 3 actor { 4 provider = "akka.remote.RemoteActorRefProvider" 5 } 6 remote { 7 enabled-transports = ["akka.remote.netty.tcp"] 8 netty.tcp { 9 hostname = "127.0.0.1" 10 port = 5150 11 } 12 log-sent-messages = on 13 log-received-messages = on 14 } 15 }
主要定义使用tcp协议的方式进行数据传输,端口是5150。这样就完成了remoteActor的定义。
而后新建一个LocalActor项目,一样修改build.sbt文件中的内容如上,而后新建一个LocalActor类,因为此处须要向RemoteActor发送消息,因此必须创建一个RemoteActor的子Actor,具体命令以下:
val remoteActor = context.actorSelection("akka.tcp://remoteSys@127.0.0.1:5150/user/remoteactor")
其中akka://remoteSys/user/remoteactor是RemoteActor经过system建立的路径,此处与之不一样的是akka后添加.tcp表示经过tcp方式建立而后就是remoteSys后经过@127.0.0.1:5150指定远程actor的IP地址以及端口。这样就可创建一个remoteActor的实例,能够经过该实例向remoteActor发送消息。
LocalActor中也须要添加application.conf文件,可是只须要添加以下语句便可:
1 akka { 2 actor { 3 provider = "akka.remote.RemoteActorRefProvider" 4 } 5 }
4、总结
本文为你们简单介绍了scala基础、sbt简单操做、原生actor、akka的并发以及并行方式actor,这些是我在学习Geotrellis的过程当中学习基础知识的一部分经验总结和梳理,只有打好基础才能更好的拓展本身的知识。要知其然并知其因此然。明白了这些对阅读Geotrellis源代码以及Spark源代码都会有很大的帮助。
5、参考连接
1、geotrellis使用初探