Scala教程(18)同時プログラミング詳細

9053 ワード


 
Scala教程(18)同時プログラミング詳細
 
 
1 Scara合併Actor
1.1 Actorの作成と起動
  Actor同時プログラムを作成し、Actorの特徴を実現し、act方法を書き換え、act方法はJavaのRunnableインターフェースのrun方法と似ています。
スレッドActorのact方法が異なるように並列に動作します。
    import scala.actors.Actor
    /*
     * Actor             ,  Actor              ,          。
     * Actor            ,              。
     *             Actor  ,                    。
     * 
     * Actor              (  :Java)    。Actor          、           。
     *   Actor    ,  (trait)Actor  ,  act  ,act   Java  Runnable   run     。
     *        Actor act           。
     */
    object FirstActor extends Actor {
      def act(): Unit = {
        //         
        println(Thread.currentThread().getName);
        List.range(1, 11).foreach {
          x =>
            println("FirstActor==>" + x); //       
            Thread.sleep(1000); //   1     
        }
      }
    }
    
    object SecondActor extends Actor {
      def act(): Unit = {
        //         
        println(Thread.currentThread().getName);
        List.range(1, 11).foreach {
          x =>
            println("SecondActor:==>" + x); //       
            Thread.sleep(1000); //   1     
        }
      }
    }
    
    object HelloActor {
      def main(args: Array[String]): Unit = {
        // start       
        FirstActor.start();
        SecondActor.start();
      }
    }
 
  

1.2 发送/接收消息

Actor是一个处理异步消息对象。你向某个Actor发送消息,该Actor处理消息,或许还会向其它Actor发送消息做进一步处理。

消息可以是任何对象,发送消息的语法:actor ! message

    import scala.actors.Actor
    import scala.actors.Actor.actor
    import scala.actors.Actor.receive
    
    //   ActorMessage  ,  Actor
    object Actor_Message extends Actor {
      //   act  
      def act(): Unit = {
        /*
         *      receive - "  "  msg        。
         *  receive   ,  apply  ,  isDefinedAt            case  ,   case  ,   true
         *       case      ,     。receive   Actor       (      )  。
         */
        while (true) {
          receive {
            case msg => println("Message content Actor from inbox:" + msg);
          }
        }
      }
    }
    //   actor
    object ActorMessage {
      def main(args: Array[String]): Unit = {
        //   actor    
        val actorMessage = actor {
          while (true) {
            //       
            receive {
              //     
              case msg: Double => println("Double Number from inbox:" + msg);
              case _           => println("Something Unkown");
            }
          }
        }
    
        //   Actor,    
        Actor_Message.start();
        /*
         *        ,  :actor ! message
         *      :Message content Actor from inbox:Hadoop
         */
        Actor_Message ! "Hadoop";
    
        /*
         *    PI
         *      :Double Number from inbox:3.141592653589793
         */
        actorMessage ! Math.PI;
        //     :Something Unkown
        actorMessage ! "Spark"
      }
    }
1.3メッセージパターンマッチング
偏関数でcase classオブジェクトタイプの情報を受信します。モードマッチングによって直接コンテンツの情報を抽出する。
    import scala.actors.Actor
    import scala.actors.Actor.self
    
    //   case Person 
    case class Person(name: String, age: Int);
    class HelloActor extends Actor {
      def act(): Unit = {
        while (true) {
          //       
          //   case     ,     ,          
          receive {
            //     ,   case class    ,     apply 
            case Person(name, age) =>
              //     :Name==>Spark:Age==>6
              println("Name==>" + name + ":Age==>" + age);
              sender ! "Echo!!!"; //         
    
            //      ,        “  ”  “  ”      。
            case _ => println("Something else...")
          }
        }
      }
    }
    
    object ActorWithCaseClass {
      def main(args: Array[String]): Unit = {
        val hiActor = new HelloActor();
        //      
        hiActor.start();
        //     
        hiActor ! Person("Spark", 6);
        //        ,    :msg==>Echo!!!
        self.receive { case msg => println("msg==>" + msg) };
      }
    }
1.4 reactキーワード
react:具体的な内容を返さないで、実は返した値はNothingで、このタイプは正常に退出しないことを表しています。
reactの呼び出しは毎回Nothingに戻り、スタックをクリアする。次のactorは、現在のactorのスレッドを再利用します。
    import scala.actors.Actor;
    import scala.actors.Actor._;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    case class Net(name: String, actor: Actor);
    
    object NameResolver extends Actor {
      def act(): Unit = {
        /*
         *  react:        ,       Nothing,          。
         *           act()  ,        ,              。
         *     react       Nothing,    。
         *     actor,    actor     。
         */
        react {
          // case    
          case Net(name, actor) =>
            sender ! getIp(name);
            act(); //              
          case "EXIT" =>
            println("Name resolver exiting.");
            act(); //                 
          case msg =>
            println("Unhandled message:" + msg);
            act(); //              
        }
      }
    
      //       Ip  
      def getIp(name: String): Option[InetAddress] = {
        try {
          //   Ip  
          println(InetAddress.getByName(name));
          //        Some
          return Some(InetAddress.getByName(name));
        } catch {
          //     ,  None
          case _: UnknownHostException => None;
        }
      }
    }
    
    object ActorMoreEffective {
      def main(args: Array[String]): Unit = {
        //      
        NameResolver.start();
        //     ,     self
        NameResolver ! Net("www.baidu.com", self)
        //        ,1    ,    :Some(www.baidu.com/61.135.169.121)
        println(self.receiveWithin(1000) { case x => x });
      }
    }
1.5 loopキーワード
loopキーワードは無限ループを作ることができます。
    import scala.actors.Actor;
    import scala.actors.Actor._;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    case class Net(name: String, actor: Actor);
    
    object NameResolver extends Actor {
      def act(): Unit = {
        /*
         *      
         *  loopWhile        , :loopWhile(count < max)
         */
        loop {
          react {
            // case    
            case Net(name, actor) =>
              sender ! getIp(name);
            case msg =>
              println("Unhandled message:" + msg);
          }
        }
      }
    
      //       Ip  
      def getIp(name: String): Option[InetAddress] = {
        try {
          //   Ip  
          println(InetAddress.getByName(name));
          //        Some
          return Some(InetAddress.getByName(name));
        } catch {
          //     ,  None
          case _: UnknownHostException => None;
        }
      }
    }
    
    object ActorMoreEffective {
      def main(args: Array[String]): Unit = {
        //      
        NameResolver.start();
        //     ,     self
        NameResolver ! Net("www.baidu.com", self)
        //        ,1    ,    :Some(www.baidu.com/61.135.169.121)
        println(self.receiveWithin(1000) { case x => x });
      }
    }
    --以上はScaraの同時プログラミングの詳細です。ご関心をありがとうございます。
                                                                                                                                                                                      ——厚ぼったい薄毛