高い同時実行Javaプログラミング-Akka

注意:最初に、読んだ後に、この記事の著者は、各章の本質をカバーしてまとめた知識、「高い同時実行Javaプログラミングを戦います」。第二に、商品コードは、ブックからの直接の引用の一部です。

アッカ高い並行プログラミングを構築する使用

1.1新しい同時実行モデル:俳優

並行プログラムでは、スレッドは、常にプログラムの同時実行の基本単位です。しかしAkka、あなたは新しい実行ユニットを使用する- Actorと、もはやスレッドの概念を必要としません。

俳優のモデルでは、我々はいくつかのビジネスロジックのコードを実行するために、オブジェクトを呼び出すために(例えば、俳優)メソッドが必要ですが、俳優にメッセージを送信することにより、ありません。アクターは、メッセージを受信した後、それは(自発ため)その状態を変更するなど、メッセージの内容に応じて動作の一部を行います

1.2.Akka之HelloWorld

最初の実現俳優

public class Greeter extends UntypedActor {

    public static enum Msg{
        GERRT, DONE;                   //消息类型
    }

    @Override
    public void onReceive(Object msg){
        if(msg == Msg.GERRT){
            System.out.println("Hello World!");
            getSender().tell(Msg.DONE, getSelf());
        } else {
            unhandled(msg);
        }
    }

}

上記のコードは、それがUntypedActor(アッカのコアメンバー)から継承する、ウェルカム人(グリーター)アクターを定義します。

  • UntypedActor:俳優の型なし、UntypedActorを継承した後、あなたは、建設、他のタイプのシステムを継承することはできません
  • システムは、このようにJavaの単一継承の問題を緩和、建設、他のタイプで使用することができます:俳優のタイプがあります。

俳優は、HelloWorldの、彼は次のように実装されている他の俳優との通信:

public class HelloWorld extends UntypedActor {

    ActorRef greeter;

    //Akka的回调方法,在Actor启动前由Akka调用完成一些初始化操作
    @Override
    public void preStart() {            
        //创建Greeter实例
        greeter = getContext().actorOf(Props.create(Greeter.class),"greeter");      
        System.out.println("Greeter Actor Path:" + greeter.path());
        //向Greeter发送GREET信息
        greeter.tell(Greeter.Msg.GERRT,getSelf());                 
    }

    //onReceive()函数为HelloWorld的消息处理函数。这里只处理了DONE消息,然后向Greeter发送了一条GREET信息
    //因此,Greeter会收到前后两条GREET消息,打印两次Hello World“”
    @Override
    public void onReceive(Object msg) throws Exception {           
        if(msg == Greeter.Msg.DONE) {
            greeter.tell(Greeter.Msg.GERRT, getSelf());
            getContext().stop(getSelf());
        } else {
            unhandled(msg);
        }
    }

}

メイン関数main():

public class HelloMainSimple {

    public static  void main(String[] args) {
        ActorSystem system = ActorSystem.create("Hello", ConfigFactory.load("samplehello.conf"));
        ActorRef a = system.actorOf(Props.create(HelloWorld.class),"helloworld");
        System.out.println("HelloWorld Actor Path:" + a.path());
    }

}
  • ActorSystem:アクターは、システムの管理と保守を表し、通常のアプリケーションでは十分なだけActorSystemが必要です。
  • ActorSystem.creat(「こんにちは」、ConfigFactory.load(「samplehello.conf」)):最初の引数は、システム名およびプロファイルのための第二引数です。ファイルsamplehello.confここでの内容は次のとおりです。
akka {
    loglevel = INFO
}

1。?。メッセージルーティング

public class WatchActor extends UntypedActor {

    private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);

    public Router router;
    {
        List<Routee> routees = new ArrayList<Routee>();
        for(int i=0; i<5; i++) {
            ActorRef worker = getContext().actorOf(Props.create(MyWorker.class),"worker_"+i);
            getContext().watch(worker);
            routees.add(new ActorRefRoutee(worker));
        }
        router = new Router(new RoundRobinRoutingLogic(),routees);
    }

    @Override
    public void onReceive(Object msg) {
        if(msg instanceof MyWorker.Msg) {
            router.route(msg, getSender());
        } else if (msg instanceof Terminated) {
            router = router.removeRoutee(((Terminated) msg).actor());
            System.out.println(((Terminated) msg).actor().path() + " is closed,routees=" + router.routees().size());
            if(router.routees().size() == 0) {
                System.out.println("Close system");
                RouteMain.flag.send(false);
                getContext().system().shutdown();
            }
        } else {
            unhandled(msg);
        }
    }

}
public class RouteMain {

    public static Agent<Boolean> flag = Agent.create(true, ExecutionContexts.global());

    public static void main(String[] args) throws InterruptedException {
        ActorSystem system = ActorSystem.create("route", ConfigFactory.load("samplehello.conf"));
        ActorRef w = system.actorOf(Props.create(WatchActor.class), "watcher");
        int i = 1;
        while(flag.get()) {
            w.tell(MyWorker.Msg.CLOSE, ActorRef.noSender());
            i++;
            Thread.sleep(100);
        }
    }

}

おすすめ

転載: blog.csdn.net/affluent6/article/details/91528482