1. 程式人生 > >討喜的隔離可變性(二)角色的特性

討喜的隔離可變性(二)角色的特性

宣告:本文是《Java虛擬機器併發程式設計》的第五章,感謝華章出版社授權併發程式設計網站釋出此文,禁止以任何形式轉載此文。

角色是一種能夠接收訊息、處理請求以及傳送響應的自由執行的活動(activity),主要被設計用來支援非同步化且高效的訊息傳遞機制。

每個角色都有一個內建的訊息佇列,該佇列與手機上所使用的簡訊佇列十分相似。假設Sally和Sean同時給Bob的手機發了簡訊,則運營商將會把這兩條簡訊都儲存起來以便Bob在方便的時候取走。類似地,基於角色的併發庫允許多個角色併發地傳送訊息。預設情況下,訊息傳送者都是非阻塞的;它們會先把訊息傳送出去,然後再繼續處理自己的業務邏輯。類庫一般會讓特定的角色順序地拾取並處理訊息佇列中訊息,只有將當前訊息處理完或將訊息委派給其他角色併發處理之後,這個角色才能夠接收下一個訊息。

角色的生命週期如圖 8‑1所示。一個角色在被創建出來之後既可以被啟動也可以被終止。一旦被啟動,角色即已準備就緒,隨時可以接收/處理訊息。當角色處於活動狀態時,則不是在處理訊息就是在等待新訊息到達。而一旦停止之後,角色就不會再接收任何訊息了。就角色的整體生命週期而言,其用於等待和處理訊息的耗時比取決於它們所處的應用程式的動態特性。

 

圖 8‑1 角色對可變狀態進行了隔離,不同角色之間通過傳遞不可變訊息來進行通訊

如果角色在程式的設計中起到了舉足輕重的作用,那麼我們就會期望在程式執行過程中建立足夠多可供使用的角色。然而執行緒是有限的資源,所以我們不能把角色與執行緒一對一地捆綁在一起。為了避免資源不足的問題,支援角色的類庫通常都會將角色與執行緒解耦。角色與執行緒之間的關係好比公司食堂和公司僱員。例如,Bob在其公司食堂裡是沒有專門的座位的(如果他想要這種待遇的話恐怕得另找一份工作了),所以每次他去食堂吃飯都是隨便找一個沒人佔的座位就行了。與此相類似地,當收到一個待處理的訊息或待執行的任務時,角色就可以分配到一個可用的執行緒來執行任務。一個好的角色在不執行任務時是不會佔住執行緒不放的,因為只有這樣才能夠讓更多不同狀態下的角色處於活動狀態,並將有限的可用執行緒資源充分地利用起來。雖然在任意時刻都可能有多個角色處於活動狀態,但在任何情況下一個角色中只有一個執行緒是活動的。這樣既保證了多個角色之間的併發性,同時又消除了單個角色之內的競爭。


方 騰飛

花名清英,併發網(ifeve.com)創始人,暢銷書《Java併發程式設計的藝術》作者,螞蟻金服技術專家。目前工作於支付寶微貸事業部,關注網際網路金融,併發程式設計和敏捷實踐。微信公眾號aliqinying。