并发编程初体验

参考文献
scala 深入浅出实战经典 . 王家林

幂等性的理解  http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html  致谢博主!

场景
scala中并发编程基本模型、匿名Actor、消息传递、偏函数实战以及 幂等性 概念
实验

package com.scode.scala
import scala.actors._
/**
 * author: Ivy Peng
 * function: 并发编程
 * 1、java中并发线程基于 数据共享与锁的机制;弊端:java中线程是一个动态的概念,容易形成死锁。
 * 2、scala中并发编程基于 消息通信模型 :不共享数据,依赖消息传递
 * 
 * 3、匿名Actor、消息传递、偏函数实战
 * idempotent 幂等:数学中的概念,表达的是N次变换与1次变换的结果相同- 即程序执行n次与执行一次的结果相同
 * date:2016/03/28 23.36
 * 语法: object ThreadName extends Actor
 */
object First_Actor extends Actor
{
  def act()
  {
    println(Thread.currentThread().getName)
    for(i<-1 to 10)
    {
      println("Step:" + i)
      Thread.sleep(2000)
    }
  }
}
object Second_Actor extends Actor
{
  def act()
  {
    println(Thread.currentThread().getName)
    for(i<-1 to 10)
    {
      println("step further:" + i)
    }
  }
}


object Actor_Message extends Actor
{
  def act()
  {
    while(true)
    {
      /*
       *  非常暖心啊!常规写法:receive(funName(args:T*){...}),而对于函数参数这种情况
       *  1、省写 funName-想想很合理啊(函数参数只关心函数的执行,不关心名称,所以该省去)
       *  2、省写 (args:T*)-合理?!如果没有参数需要传递,像本例这种情况。
       *  综上,写 receive({...})即可 -》 再优雅一点的写法: receive{}
       */
//      receive({ 
//        case msg => println("Message from inbox :"+msg)
//      })
      //终极写法
      receive //从邮箱中获取一条消息,并传递给偏函数
      {
        case msg => println("------- Message from inbox -------:"+msg)
      }
      
    }
  }
}

object HelloActor
{
  def main(args: Array[String]): Unit =
  {
      /*
       * 初体验
       */
//      val actor1 = First_Actor.start() //Starts this actor. This method is idempotent. 
    	// First_Actor.start() 由于start方法是幂等的,因此调用一次与调用多次执行效果是 一样的
//      val actor2 = Second_Actor.start() 
      
      /*
       * 匿名函数的两种编写方式 与 消息传递、偏函数实战
       */
      
      val actor_Messager = new Actor{// 方式一,与java中的匿名函数方式编写类似,只是这里可以省略()
        def act()// ? 该方式编译器没有报错,但是实际运行,控制台没有输出结果-》有待后续进一步分析
        {
          while(true)
          {
            receive
            {
              case msg:String => println("Message from inbox :"+msg)
              case _ => println("Something else from inbox !")
            }
          }
        }
      }
      
       import scala.actors.Actor._ //方式二、使用scala.actors.Acotor.actor工具方法
       val double_Messager = actor 
       {
          while(true)
          {
            receive
            {
              case msg : Double => println("Message from inbox :"+msg)
            }
          }
      }
  
      Actor_Message.start
      Actor_Message!"hadoop"
      actor_Messager ! "Spark your life !"
      double_Messager ! "Spark your life !"//分布式系统中,“忽略消息类型非法的处理很合理”
      double_Messager ! Math.PI
  }
}
实战

编写程序,获取输入域名的实际IP地址

package com.scode.scala
import scala.actors.Actor
import scala.actors.Actor._
import java.net.InetAddress
import java.net.UnknownHostException
object NameResolver extends Actor
{
  def act()
  {
//    react
//    {
//      case Net(name,actor)=>
//        sender ! getIp(name)
//        act
//      case "EXIT" => println("Name resolver exiting.")
//      case msg =>
//        println("Unhandled message:"+msg)
//        act
//    }
    loop
    {
      react
      {
        case Net(name,actor)=>
          sender ! getIp(name)
        case msg =>
          println("Unhandled message:"+msg)
      }
    }
  }
  
  /*
     * 根据域名,获取IP地址
     */
    def getIp(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 Actor_More_Effective
{
  def main(args: Array[String]): Unit =
  {
    val actor = NameResolver.start()
    actor ! Net("www.baidu.com",self)
    
    println(self.receiveWithin(1000){case x=> x})
  }
}

执行 结果

并发编程初体验_第1张图片


你可能感兴趣的:(并发编程初体验)