import scala.actors.{!, Channel, OutputChannel, Actor}
import scala.actors.Actor._
case class compute(intput:Int,result:OutputChannel[Int])  创建一个case类,一边在case 中接受数据
object main{
  def main(args: Array[String]) {

    a.start()   // 启动线程a,b
    b.start()
  }
  val a = actor{  // 用actor单例对象实例化一个线程,也可以写一个类继承Actor实现一个线程
    
    // link(b)   关联b actor,关联是双向的,一方退出,另一方会得到通知
    self.trapExit = true // true表示关联actor退出时,自己可以继续运行。false表示关联actor退出时,自己也退出。(默认是false)
    println("a send 1 to b")
    val ca = new Channel[Int]()  // 创建一个channel绑定当前actor,也可以通过参数绑定其他actor。(绑定哪个actor,哪个actor就可以从这个channel中读信息)
    b ! compute(1,ca)      // 想actor b发送一个数据(数据包含参数,消息通道)
    // var res = b !? compute(1,ca)  !? 表示发送消息后阻塞,直到消息返回(我自己测试没有成功,感觉也没有用处,如果只是要阻塞,receive默认就会阻塞)
    // var res = b !! compute(1,ca)  !! 表示返回一个future类型的值(该语句不阻塞,等res被用到时且b依然没有返回值才阻塞,也可以称之为懒阻塞)
    while (true){
      receiveWithin(5000) {   // 指定超时时间,超时会触发一个timeout异常
        case !(ca,x) => println("a recv ",x," from b") // 从一个channal中读信息
        // case Exit(from,reason) => println(from,reason)  // 当使用了link将多个actor关联起来时,用于捕获关联的actor异常退出,
        case _ => println("recv nothing")
      }
    }
  }
  val b = actor{
    while (true){
      receive {           // 不指定超时,会一直阻塞
        case compute(input, res) => { // input代表发送过来的数据,res代表给我发消息的是哪个actor,可以通过这个值回复源actor
          println("b recv:", input)
          println("b send 2 to a")
          res ! 2   // 回复源actor
        }
      }
    }
  }
}