Scala Actot(二):共享--react,loop,loopwhile实现共享以及while的共享失效性

一、前言

考虑一个发送消息给另一个actor的actor。如果每个actor都在单独的线程中运行,我们很容易实现控制流转。作为消息发送方的actor将消息发到邮箱中,然后它的线程继续执行。而每当有条目被放入邮箱时,作为消息接收方的actor的线程就会被唤醒。

在有些程序所包含的actor是如此之多,以至于要为每个actor创建独立的线程开销很大。所以实际需求中,我们肯定不能这样做,我们必须使得一个actor可以多次被使用,而不是频繁地创建,销毁。

二、react控制流原理以及while的共享失效性

以下采用快学scala教材的一个例子:

2-1 例子:react的控制流原理

/**
   * 这里的Withdraw,Confirm分别是两个不同类型的函数
   */
  react{//函数f1
    case Withdraw(amount) =>
      react {//函数f2
        case Confirm() =>
          println("Confirming "+amount)
      }
   }
它的控制流过程是这样的:第一个react的调用讲将f1与actor的邮箱关联起来,然后退出。当Withdraw消息抵达时,f1被调用。函数f1也调用了react。这次调用把f2与actor的邮箱关联起来;然后退出。当Confirm消息抵达时,f2被调用。

由于react会退出,所以你不能简单地把它放进whlile循环中

2-2例子:while的共享失效性

<pre name="code" class="java"><pre name="code" class="java"> while(true){
    react{//函数1
      case Withdraw(amount) =>
          println("Confirming "+amount)
   }
    print("haha")//这个句子在react被调用并把f1函数送到邮箱时,立马执行。这意味着print(“haha”)与react执行体不在同一个线程内串行执行
}

 
 

这个例子中,react执行体会被送到邮箱中,可以理解为它的执行是在另一个线程里。这也意味着需要重复利用的actor在print("haha")后就自动挂掉,无法重复利用。


2-3例子:actor重复利用

</pre><pre name="code" class="java">def act(){
    react{//函数1
      case Withdraw(amount) =>
          println("Confirming "+amount)   <pre name="code" class="java">      act()
} }

 
这样做就意味着用一个无穷递归来替换无穷循环 
</pre>2-4例子:scala中loop,loopwhile()可以实现这种“控制流转组合子”</p><p><pre name="code" class="java">def act(){
  loop{
    react{//函数1
      case Withdraw(amount) =>
          println("Confirming "+amount)
   }
  }
}


三、react 实例

以下使用 无穷递归的方式来共享Actor

3-1经典例子:

<pre name="code" class="java">import java.net.InetAddress  
import java.net.UnknownHostException   
import actors._, Actor._  
import scala.actors.Actor  
  
/** 
 * scala Actor构建在java的线程基础之上的, 
 * 为了避免频繁的线程创建、销毁和切换等,scala中提供了react方法 
 * 方法执行完毕后,仍然被保留 (这里是指线程)
 */  
object NameResolver extends Actor{  
  def act(){  
    react{  
      /** 
         * 该例中,以下所有内容都会与邮箱关联起来,让邮箱去执行,然后当前react退出,
         * 所以说当前react是没有任何办法返回到当前act()方法当中
         * 下面会调用act来构造一个无限递归
         */ 
      case Net(name,actor) =>  
          
        actor!getIpAddress(name)  //
        //再次调用act方法,从本身邮箱中读取消息 ,如果消息为空,则等待  
        //这里act相当在无限递归自身方法
        act
        
      case "EXIT" =>  
        println("Name resolver exiting.")  
        //匹配邮箱中的单个信息,本例中会匹配邮箱中的IP地址信息  
      case msg =>  
        println("Unhandled message: " + msg)  
        act  
    }  
  }  
    
  def getIpAddress(name:String):Option[InetAddress] ={  
    try{  
       println(InetAddress.getByName(name))  
       Some(InetAddress.getByName(name))  
    } catch {  
      case _: UnknownHostException => None  
    }  
  }  
}  
case class Net(name:String,actor:Actor)  
  
object ActorWithReAct extends App {  
  //启动Actor  
  NameResolver.start()  
  //发消息  
  NameResolver!Net("www.baidu.com",self)  
    
  //接收消息  
  println(self.receive{case msg => msg})  
}  


 3-2结果 

www.baidu.com/14.215.177.38
Some(www.baidu.com/14.215.177.38)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值