High concurrency Java programming -Akka

Note: First, the author of this article after reading "combat high concurrency Java programming" summarized knowledge, which covers the essence of the each chapter. Second, the article code is part of a direct quote from the book.

Use Akka build high concurrent programming

1.1 New concurrency model: Actor

In the concurrent program, a thread is always the basic unit of concurrent execution of the program. However Akka, you will use a new execution units - Actor, and no longer need the concept of threads.

In the Actor model, we do not need to call objects (e.g. Actor) method to perform some business logic code, but by sending a message to the Actor. Actor After receiving the message, it will make some of the acts in accordance with the content of the message, including changing its status (for spontaneous)

1.2.Akka Noriyuki HelloWorld

The first realization Actor

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);
        }
    }

}

The above code defines a welcome person (Greeter) Actor, it inherits from UntypedActor (core members of Akka).

  • UntypedActor: untyped of Actor, after inheriting UntypedActor you can not inherit the system to other types of construction
  • There are types of Actor: The system can be used in other types of construction, thus easing Java single inheritance issues

Communicate with another Actor Actor is HelloWorld, he implemented as follows:

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 function 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: Actor represents the management and maintenance of the system, usually an application requires only a ActorSystem enough.
  • ActorSystem.creat ( "Hello", ConfigFactory.load ( "samplehello.conf")): The first argument is the system name and the second argument for the profile. Content here samplehello.conf file is:
akka {
    loglevel = INFO
}

1.?. Message Routing

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);
        }
    }

}

Guess you like

Origin blog.csdn.net/affluent6/article/details/91528482