1 背景
傳統(tǒng)編程模型認(rèn)為寫一個變量就是直接寫了相應(yīng)的內(nèi)存地址,但是在現(xiàn)代計(jì)算機(jī)架構(gòu)中CPU寫的是cache lines而不是直接寫內(nèi)存,這些緩存大部分是L1一級緩存,也就是說CPU的一個核寫的內(nèi)容另外的核看不見,為了把變化廣播給別的核(這樣才能同樣廣播到別的線程),需要把cache line的變化同步到其他核的cache。
JVM運(yùn)行環(huán)境下,要做到上述的線程間共享,需要顯式地給變量打上volatile 標(biāo)記或者使用Atomic原子包裝數(shù)據(jù)結(jié)構(gòu)或者使用鎖哥艇。否則,一般變量值的變化不保證能實(shí)時同步給其它線程可見胜嗓。為什么不標(biāo)記所有變量都是volatile的呢?因?yàn)樵贑PU的多個核之間同步cache lines是很昂貴的操作亡笑!會拖慢CPU內(nèi)核速度并且導(dǎo)致cache coherence protocol (the protocol CPUs use to transfer cache lines between main memory and other CPUs) 瓶頸,最終明顯的拖慢運(yùn)行泼返。
2 Actor簡介
Actor模型首先是由Carl Hewitt在1973定義秫舌, 由Erlang OTP 推廣瑰步,其消息傳遞更加符合面向?qū)ο蟮脑家鈭D矢洲。Actor屬于并發(fā)組件模型,通過組件方式定義并發(fā)編程范式的高級階段缩焦,避免使用者直接接觸多線程并發(fā)或線程池等基礎(chǔ)概念读虏。簡單理解為 Actor模型=狀態(tài)+行為+消息。
2.1 面向?qū)ο?/h3>
Actor 模型本質(zhì)上是一種計(jì)算模型袁滥,基本的計(jì)算單元稱之為Actor 盖桥,換言之,在Actor 模型中题翻,所有的計(jì)算都是在Actor 中執(zhí)行的揩徊。在面向?qū)ο缶幊汤锩妫磺卸际菍ο竺晡眨贏ctor模型里面靴拱,一切都是Actor ,并且Actor 之間完全隔離的猾普,不會共享任何變量。
2.2 無鎖
在并發(fā)編程中常需要關(guān)注鎖和內(nèi)存原子性等一系列線程問題本谜,而Actor模型內(nèi)部的狀態(tài)由它自己維護(hù)即它內(nèi)部數(shù)據(jù)只能由它自己修改(通過消息傳遞來進(jìn)行狀態(tài)修改)初家,所以使用Actors模型進(jìn)行并發(fā)編程可以很好地避免這些問題。Actor內(nèi)部是以單線程的模式來執(zhí)行的乌助,類似于redis溜在,所以Actor完全可以實(shí)現(xiàn)分布式鎖類似的應(yīng)用。
2.3 異步
Actor中的異步是通過各自的MailBox來實(shí)現(xiàn)的他托,Actor間進(jìn)行邏輯交互時只需要把消息傳遞到對應(yīng)的MailBox里掖肋。
2.4 容錯
對于傳統(tǒng)的編程方式都是在將來可能出現(xiàn)異常的地方去捕獲異常來保證系統(tǒng)的穩(wěn)定性,即防御式編程赏参。但對于防御式編程志笼,防御的一方永遠(yuǎn)不能100%的防御住所有將來可能出現(xiàn)代碼缺陷的地方沿盅。比如在java代碼中很多地方充斥著判斷變量是否為null,這些就屬于防御式編碼最典型的案例纫溃。但是Actor模型的程序并不進(jìn)行防御式編程腰涧,而是遵循“任其崩潰”的哲學(xué),讓Actor的管理者們來處理這些崩潰問題紊浩。比如一個Actor崩潰之后窖铡,supervisor可以選擇創(chuàng)建新的實(shí)例或者記錄日志。每個Actor的崩潰或者異常信息都可以反饋到supervisor那里坊谁,這就保證了Actor系統(tǒng)在管理每個Actor實(shí)例的靈活性费彼。
3 MailBox
每個actor都有且僅有一個mailbox,mailbox相當(dāng)于一個小型的隊(duì)列口芍,一旦sender發(fā)送消息敌买,就將該消息入隊(duì)到mailbox中。入隊(duì)的順序按照消息發(fā)送的時間順序阶界。這樣的設(shè)計(jì)解耦了actor之間的關(guān)系虹钮,每個actor都處理各自的mailbox?。雖然所有actor可以同時運(yùn)行膘融,但它們處理mailbox消息時只能當(dāng)前消息處理完畢后才會處理下一個消息芙粱。
當(dāng)一個actor接收到消息后,它能做如下三件事中的任意一件:
- 創(chuàng)建有限數(shù)量的新actors
- 發(fā)送有限數(shù)量的消息給其他參與者
- 指定下一條消息到來時的行為
劣勢:
1氧映、Actor模型需要一個緩沖隊(duì)列來緩沖消息春畔。
2、由于Actor是在進(jìn)程內(nèi)保存自己狀態(tài)的岛都,因此無法統(tǒng)一控制Actor的生命周期律姨。在內(nèi)存使用過量時不能像無狀態(tài)服務(wù)通過淘汰機(jī)制進(jìn)行內(nèi)存控制。
3臼疫、Actor 系統(tǒng)需要關(guān)注mailBox的設(shè)計(jì)择份。
使用場景:
1、有資源競爭的功能都可以使用Actor模型烫堤。
2荣赶、需要做到水平擴(kuò)容的服務(wù)。