标签(空格分隔): hadoop scala
前言
前两节我们学习了scala的基础语法,包括基本类型,流程控制,模式匹配,和对应的类,对象,特征的定义,那么在java中我们知道,为了提高效率不可避免的会用到异步,线程提高我们的处理效率。今天我们来学习下scala的并发编程,闲话少说我们下面进入正题。
Actor
Actor基础类库使用简介
2.10之前是使用Actor作为并发编程模型,2.10以后采用Akka作为并发编程, 老版本的Actor已然废弃,但我们今天需要先学习下老版本的Actor学习一下编程模型和机制。
上图就是一个完美诠释Actor的多线程机制。
通过消息传递,类似投递箱 异步获取信息处理。所以人家与java的多线程机制有点不大一样,人家设计的这种就是通过尽可能避免锁争用和共享状态。让我们使用的时候更容易设计出线程安全的并发程序(但是如果涉及到actor内部操作外部的状态是可能存在线程安全问题的)。
actor中通常使用receive和react来完成获取消息处理流程。消息传递的方式有多种
符号 | 描述 |
---|---|
! | 异步发送没有返回值 |
!! | 异步发送返回future |
!? | 同步并等待消息返回 |
通常actor的设计尽量避免共享变量,比如我们通过actor完成消息处理后的汇总,我们可以使用ConcurrentHashMap来完成汇总,但在scala中你可以使用这个actor持有另外一个汇总acotr完成消息异步发送。
以下我们将进行actor的demo使用。
actor的demo
package com.lcy.scalabasic.actors
/**
* Created by luo on 2019/8/11.
*/
class ActorDemo extends actors.Actor{
override def act(): Unit = {
//循环获取消息,如果没有消息会Block
while(true){
receive {
case "hello" => println("hello")
}
}
}
}
class ActorDemo2 extends actors.Actor{
//如果需要返回值可以使用这个方法,然后让消息方发送的消息使用!? 同步获取 但强烈不建议这样使用
override def act(): Unit = {
receive{
case "hello" => sender ! "give you world"
}
}
}
class ActorDemo3 extends actors.Actor{
override def act(): Unit = {
//这回我们还是使用重复接受消息的形式,让actor可以一直获取消息
while(true){
receive{
case "hello" => sender ! "i give you word"
}
}
}
}
object ActorDemo{
def main(args: Array[String]): Unit = {
val ac = new ActorDemo
ac.start()
ac ! "hello"
val ac2 = new ActorDemo2
ac2.start()
val result = ac2 !? "hello"
println(s"syc result $result")
val ac3 = new ActorDemo3
ac3.start()
val future = ac3 !! "hello"
//FutureActor
println(future.isSet)
val c = future.apply()
println(future.isSet)
println(c)
}
}
这里说明一下 receive之内其实是一个偏函数,当然您也不适用receive而直接起一个线程使用处理程序。
receive和react的区别
reactor会复用线程,避免频繁的创建和销毁线程
当使用receive时,程序为每个actor都单独创建一个线程,如没有接收到消息,该线程也会一直保持等待,不可以其他任务复用。
当使用react时,actor不会单独占用线程,只有当接收到消息程序才会为该actor分配线程,非常节省资源。(类似懒加载)
package com.lcy.scalabasic.actors
/**
* Created by luo on 2019/8/11.
*/
class ActorReceive extends actors.Actor{
override def act(): Unit = {
while(true){
receive{
case "hello" => println("i am actorreceive thread of " + Thread.currentThread())
}
}
}
}
class ActorReact extends actors.Actor{
override def act(): Unit = {
loop{//必须用loop快学scala中有解释 react处理完之后就退出所以没法返回到while循环中
react{
case "hello" => println("i am actorReact thread of " + Thread.currentThread())
}
}
}
}
object ActorReceive{
def main(args: Array[String]): Unit = {
for(i <- 1 to 10){
new ActorReceive().start() ! "hello"
}
for(i <- 1 to 10){
new ActorReact().start ! "hello"
}
}
}
立个flag
在后续等有时间回过头来,写下针对Actor的相关其他概念,比如消息传递的种类,还有管道的使用等等。