注:其一、本文章為作者讀完《實(shí)戰(zhàn)Java高并發(fā)程序設(shè)計(jì)》之后所總結(jié)的知識(shí),其中涵蓋了每一章節(jié)的精髓之處毁兆。其二、文章中一部分代碼直接引自書(shū)中次询。
使用Akka構(gòu)建高并發(fā)程序設(shè)計(jì)
1.1.新并發(fā)模型:Actor
在并發(fā)程序中荧恍,線(xiàn)程始終是并發(fā)程序的基本執(zhí)行單元。但是在
Akka
中屯吊,你將會(huì)使用一個(gè)全新的執(zhí)行單元—Actor
送巡,而不再需要線(xiàn)程的概念。
在Actor模型中盒卸,我們不在需要調(diào)用對(duì)象(例如Actor)的方法去執(zhí)行一些業(yè)務(wù)邏輯代碼骗爆,而是通過(guò)給Actor發(fā)送一條消息。Actor接收到消息之后蔽介,它會(huì)根據(jù)消息的內(nèi)容做出一些行為摘投,包括改變自身的狀態(tài)(自發(fā)式進(jìn)行)
1.2.Akka之HelloWorld
第一個(gè)Actor實(shí)現(xiàn)
public class Greeter extends UntypedActor {
public static enum Msg{
GERRT, DONE; //消息類(lèi)型
}
@Override
public void onReceive(Object msg){
if(msg == Msg.GERRT){
System.out.println("Hello World!");
getSender().tell(Msg.DONE, getSelf());
} else {
unhandled(msg);
}
}
}
以上代碼定義了一個(gè)歡迎者(Greeter)Actor,它繼承自UntypedActor(Akka的核心成員)虹蓄。
- UntypedActor:為無(wú)類(lèi)型的Actor犀呼,繼承UntypedActor之后就不能再繼承系統(tǒng)中其他類(lèi)型的構(gòu)造
- 有類(lèi)型的Actor:可以使用系統(tǒng)中其他類(lèi)型的構(gòu)造,從而緩解Java單繼承的問(wèn)題
與Actor交流的另外一個(gè)Actor是HelloWorld薇组,他的實(shí)現(xiàn)如下:
public class HelloWorld extends UntypedActor {
ActorRef greeter;
//Akka的回調(diào)方法外臂,在Actor啟動(dòng)前由Akka調(diào)用完成一些初始化操作
@Override
public void preStart() {
//創(chuàng)建Greeter實(shí)例
greeter = getContext().actorOf(Props.create(Greeter.class),"greeter");
System.out.println("Greeter Actor Path:" + greeter.path());
//向Greeter發(fā)送GREET信息
greeter.tell(Greeter.Msg.GERRT,getSelf());
}
//onReceive()函數(shù)為HelloWorld的消息處理函數(shù)。這里只處理了DONE消息律胀,然后向Greeter發(fā)送了一條GREET信息
//因此宋光,Greeter會(huì)收到前后兩條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);
}
}
}
主函數(shù)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 : 表示管理和維護(hù)Actor的系統(tǒng),一般一個(gè)應(yīng)用只需要一個(gè)ActorSystem 就夠了罪佳。
- ActorSystem.creat("Hello", ConfigFactory.load("samplehello.conf")):第一個(gè)參數(shù)表示系統(tǒng)名稱(chēng)逛漫,第二個(gè)參數(shù)為配置文件。此處samplehello.conf文件的內(nèi)容為:
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);
}
}
}
文集推薦:
Java基礎(chǔ)方法集1
Python基礎(chǔ)知識(shí)完整版
Spring Boot學(xué)習(xí)筆記
Linux指令進(jìn)階
Java高并發(fā)編程
SpringMVC基礎(chǔ)知識(shí)進(jìn)階
Mysql基礎(chǔ)知識(shí)完整版
健康管理系統(tǒng)學(xué)習(xí)花絮(學(xué)習(xí)記錄)
Node.js基礎(chǔ)知識(shí)(隨手筆記)
MongoDB基礎(chǔ)知識(shí)
Dubbo學(xué)習(xí)筆記
Vue學(xué)習(xí)筆記(隨手筆記)
聲明:發(fā)表此文是出于傳遞更多信息之目的赘艳。若有來(lái)源標(biāo)注錯(cuò)誤或侵犯了您的合法權(quán)益酌毡,請(qǐng)作者持權(quán)屬證明與本我們(QQ:981086665;郵箱:981086665@qq.com)聯(lián)系聯(lián)系蕾管,我們將及時(shí)更正阔馋、刪除,謝謝娇掏。