scala actor

来源:互联网 发布:mysql partition by 编辑:程序博客网 时间:2024/05/22 10:32

1.actor用法

Scala会建立一个线程池共所有Actor来使用。receive模型是Actor从池中取一个线程一直使用;react模型是Actor从池中取一个线程用完给其他Actor用。

用法1:

import scala.actors._

object ActorSimple extends Actor {

// 实现线程

def act: Unit = {
    react {
      case n : Int => println(n)
    }
  }

}

//发送消息:

ActorSimple.start ! 1001 // 需要调用start


用法2:

import scala.actors.Actor._

val a1 = actor { react { case _ =>println("ok") } } // 马上启动

//发送消息:

a1 ! "message" // 不必调用start


提示:

!发送异步消息,没有返回值!?发送同步消息,等待返回值(阻塞发送消息的线程)!!发送异步消息,返回值是 Future[Any]?不带参数。查看 mailbox 中的下一条消息(每个actor中都有一个mailbox)。

2.接收消息

用法1:receive

如果要重复接收消息,需要用到while循环。

var flag = true

def act(): Unit = {
        while (flag) {
          receive { //或者用receiveWith(1000),1000是超时时间
            case str : String =>
              println(str)
          }
        }
      }

用法2:react

(1)要反复执行消息处理,react外层用loop,不能用while()

(2)从不返回,通过复用线程,比receive更高效,应尽可能使用react

val a1 = Actor.actor{
      loop {
        react {
          case s : String => println(s)
        }
      }
    }


3.良好的actor风格

3.1 不阻塞actor

actor不应由于处理某条消息而阻塞,可以调用helper-actor处理耗时操作(helper actor虽然是阻塞的,但由于不接受消息所以没问题),以便actor接着处理下一条消息

import actors._, actors.Actor._ 

val time = 1000 

  // (1)原来阻塞的程序

  val mainActor1 = actor {

    loop { 

      react {

        case n: Int => Thread.sleep(time)

                         println(n)

        case s : String => println(s) } }

  }

  1 to 5 foreach { mainActor1 ! _ } // 5秒钟后打印完数字

 

  // (2)改写由helper actor去阻塞的程序

  val mainActor2: Actor = actor {

    loop { react {

        case n: Int => actor { Thread.sleep(time); mainActor2 ! "wakeup" }

                        println(n)

        case s => println(s) } }

  }

  1 to 5 foreach { mainActor2 ! _ } // 马上打印数字; 1秒钟后打印5个wakeup


0 0