我在刚接触Actor的时候,看过王XX这个大专(坑)家(B)的部分视频,看到有一个scala的视频说了loop和react,不吹不黑,视频10分钟,广告6分钟!我也没有仔细看,没来想着能不能有点新发现,后台他也就是很泛泛的说了说代码。

但是我始终不知道为什么大部分教程(入门级)介绍Actor的例子的时候基本都是三个

1、receive只能接收一次消息并执行返回

2、因此使用 while(true) { receive }

3、实际中很多用到的是 react

4、react 每次要调用一次 act方法

5、因此使用 loop  不需要调用act方法

起初我觉得,多么有道理的一个顺序,后来自己试了试,发现无论是receive 还是 react 都可以直接调用act,都可以使用loop,都可以while(true)。

为何很多教程(尤其是视频)还有部分博文(其中很多转载和COPY的)都简单说说,这是一个很不好的部分。虽然没有很大的坏的影响,但是人云亦云,一点都没有指出比较深入一点的东西,会误人学习的思想。

当然至于为什么使用react而不是用receive,我都坚持《Progamming in scala》里面说的(虽然我一开始并不明白什么啥意思)

由于react方法不需要返回,其实现不需要保留当前的调用站栈。因此actor库可以在被唤醒的下一个线程中重用当前线程

 


package main.scala.S_01_LIANTEST.Test1.ActorTest

import scala.actors.Actor
import scala.actors.Actor._
import java.net.InetAddress
import java.net.UnknownHostException
/**
  * Created by Postbird on 2016/10/8.
  */
//用于通过域名求地址 需要引入java net的两个包
trait IpAction{
    def getIp(name:String):Option[InetAddress]={
        try{
            println(InetAddress.getByName(name))
            //打印一次域名
            //通过 Option 进行返回
            // Option 真的是个很有用的东西,但是一开始的时候总是用不好
            Some(InetAddress.getByName(name))
        }catch{
            case _ :UnknownHostException => None
        }
    }
}
//通过react方式  需要每次执行完后 再次调用act方式的实现

object ReactTest extends Actor with IpAction{
    def act(): Unit ={
        react{
            case Net(name,actor)=>
                actor ! getIp(name)
                act
            case "EXIT"=>println("Name resolver exiting!")
            case msg=>
                println("Unhandled message : "+ msg)
                act
        }
    }
}
//使用loop不需要再次调用act方法
object LoopTest extends Actor with IpAction{
    def act(): Unit ={
        loop{
            react{
                case Net(name,actor)=>
                    actor ! getIp(name)
                case "EXIT"=>println("Name resolver exiting!")
                case msg=>
                    println("Unhandled message : "+ msg)
            }
        }
    }
}
//每个人一开始学习的时候 第一个例子肯定是 receive
//然后教程说  receive只能调用一次,
//然后就说while true
//然后就没有然后了........
object ReceiveTest extends Actor with IpAction{
    def act(): Unit ={
        while(true){
            receive{
                case Net(name,actor)=>
                    actor ! getIp(name)
                case "EXIT"=>println("Name resolver exiting!")
                case msg=>
                    println("Unhandled message : "+ msg)
            }
        }
    }
}
//于是乎 我把while(true)去掉了
// 然后  并没有什么区别
//然而为什么建议使用loop结合react呢
// programing in scala 中这样说的
// 由于react方法不需要返回,其实现不需要保留当前的调用站栈。因此actor库可以在被唤醒的下一个线程中重用当前线程
object ReceiveLoopTest extends Actor with IpAction{
    def act(): Unit ={
        loop{
            receive{
                case Net(name,actor)=>
                    actor ! getIp(name)
                case "EXIT"=>println("Name resolver exiting!")
                case msg=>
                    println("Unhandled message : "+ msg)
            }
        }
    }
}
case class Net(name:String,actor:Actor)

object ReactLoopTest1 extends App{
//    ReactTest.start()
//    ReactTest ! Net("www.baidu.com",self)
//    self.receive{case msg=>println(msg)}
//
//    LoopTest.start()
//    LoopTest ! Net("www.baidu.com",self)
//    LoopTest ! Net("www.souhu.com",self)
//    LoopTest ! Net("www.qq.com",self)
//    LoopTest ! Net("www.ptbird.cn",self)
//    self.receive{case msg=>println(msg)}

//    ReceiveTest.start()
//    ReceiveTest ! Net("www.baidu.com",self)
//    ReceiveTest ! Net("www.souhu.com",self)
//    ReceiveTest ! Net("www.qq.com",self)
//    ReceiveTest ! Net("www.ptbird.cn",self)

        ReceiveLoopTest.start()
        ReceiveLoopTest ! Net("www.baidu.com",self)
        ReceiveLoopTest ! Net("www.souhu.com",self)
        ReceiveLoopTest ! Net("www.qq.com",self)
        ReceiveLoopTest ! Net("www.ptbird.cn",self)
//    www.baidu.com/119.75.218.70
//    www.souhu.com/124.16.31.154
//    www.qq.com/115.25.209.39
//    www.ptbird.cn/118.193.173.190
}