注意:最初に、読んだ後に、この記事の著者は、各章の本質をカバーしてまとめた知識、「高い同時実行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);
}
}
}