本文主要講解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使用初探