【java】CountDownLatch運用場景(1)
基本功能
CountDownLatch也叫閉鎖,使得一(多)個主執行緒必須等待其他執行緒完成操作後再執行。
使用的方式是:CountDownLatch內部維護一個計數器,主執行緒先執行await方法,如果此時計數器大於0,則阻塞等待。當一個執行緒完成任務後,計數器值減1。直到計數器為0時,表示所有的執行緒已經完成任務,等待的主執行緒被喚醒繼續執行。
應用場景:應用程式的主執行緒希望在負責啟動框架服務的執行緒已經完成之後再執行。
應用:快取載入
在廣告的核心引擎中,我們的服務需要載入很多快取資料,載入完成之後,主執行緒才能啟動對外提供服務。這個時候我們就用到了CountDownLatch來定時載入快取。快取載入的東西我們之後再單獨開帖子講,這裡先看CountDownLatch的使用。
定義載入快取的job抽象類
public abstract class BaseCacheUpdateJob { //job的名字 public String name() { return this.getClass().getSimpleName(); } //job的執行週期 public long getPeriodInSecond() { return PERIOD_ONE_HOUR; } //job的重要性 public boolean isEssential() { return false; } //job的具體內容 public abstract boolean update(); }
實現需要的job
//載入App資料的cache.@Componentpublic class AppCache extends BaseCacheUpdateJob { private Map<String, String> map = new HashMap<>(); @Autowired public AppCache() { } @Override public long getPeriodInSecond() { return PERIOD_ONE_MINUTE; } public String getValueByKey(String appId) { return map.getOrDefault(appId, "not find in appCache"); } @Override public boolean update() { map.put("add", "0"); return true; } }//載入廣告資料的cache.@Componentpublic class AdCache extends BaseCacheUpdateJob { private Map<String, String> map = new HashMap<>(); @Autowired public AdCache() { } @Override public long getPeriodInSecond() { return PERIOD_ONE_MINUTE; } public String getValueByKey(String appId) { return map.getOrDefault(appId, "not find in AdCache"); } @Override public boolean update() { map.put("add", "0"); return true; } }// 載入使用者畫像的cache// 載入Ctr預估模型的cache// 載入黑白名單的cache// 載入配置項的cache// ...
開始載入快取
上面兩步我們定義好了我們服務啟動的時候需要幹什麼事情,那麼具體怎麼幹,就交給了CountDownLatch
@Service@Slf4jpublic final class InterCacheService { //這裡spring的自動注入會把定義好的Bean全部注入進來記憶體 @Autowired private List<BaseCacheUpdateJob> cacheUpdateJobs; @PostConstruct private void start() { //定義執行緒池 ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(cacheUpdateJobs.size()); CountDownLatch completeTaskLatch = new CountDownLatch(cacheUpdateJobs.size()); for(BaseCacheUpdateJob job : cacheUpdateJobs) { boolean loadStatus = job.update(); if (loadStatus) { countDownLatch.countDown(); } } //阻塞住,等待上面的載入完,才會執行主執行緒. completeTaskLatch.await(); //快取載入到記憶體中了,主執行緒可以繼續載入其他bean,完成之後提供服務. } }
這裡只是舉個例子,簡化了很多程式碼,這種程式碼肯定不能在生產環境跑的,這麼跑肯定會出問題的。
比如:
1.考慮這麼一個場景,如果快取是一個不那麼重要的,你的服務其實是可以起來的。那麼如何管理這種狀態呢?
2.還有可能出現快取依賴的問題,載入AdCache需要依賴於AppCache,載入AppCache需要依賴BlackListCache,怎麼管理這種狀態呢?
3.快取沒載入成功,我什麼時候去嘗試呢?隔多久?
4.快取都在同一個時間點去載入,導致我線上的GC壓力比較大怎麼辦?
5.快取一般是多執行緒訪問的公共資源,那麼怎麼線上程安全和效能之間做取捨呢?
我後面單獨開幾篇帖子講快取,有興趣的小夥伴可以先看下這個小框架的原始碼。
作者:碼蹄疾
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2249/viewspace-2818120/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- exists、in的運用場景
- JUC之CountDownLatch的原始碼和使用場景分析CountDownLatch原始碼
- 小程式的場景入口運用技巧
- 小程式使用場景:線上場景運用如何獲得使用者
- 雲端計算日常運用場景介紹!
- API介面的運用場景以及獲取方式API
- 小程式案例:公共交通場景的運用
- MVP那些事兒(1) 用場景說話MVP
- Javascript二進位制運算子的一些運用場景JavaScript
- 好程式設計師Java教程分享Zookeeper基本原理與運用場景程式設計師Java
- 「進擊Redis」六、Redis List運用場景、API解析RedisAPI
- 淺談微信公眾平臺運用的場景
- java中ThreadLocal的應用場景分析Javathread
- audio 應用:聲波通訊(1)應用場景
- java原始碼-CountDownLatchJava原始碼CountDownLatch
- java CountDownLatch 詳解JavaCountDownLatch
- lazada商品詳情API介面運用場景及功能API
- 數字化轉型辦公室的運用場景有哪些?
- [譯] Java 資料流的不同應用場景Java
- Spark適用於哪些場景?不適用於哪些場景?Spark
- 1v1同城交友直播app原始碼開發功能完善java後臺應用場景廣APP原始碼Java
- ES 應用場景
- redis實用場景Redis
- Zookeeper應用場景
- 3.4 應用場景
- DDD應用場景
- Java反射詳解:入門+使用+原理+應用場景Java反射
- Java學習之反射機制及應用場景Java反射
- 【實操】小程式的應用場景分析——線下場景應用
- 運維場景下的兩個自我運維
- 遊戲新手教學的5種基本方式及其運用場景研究遊戲
- 雲虛擬主機運用於哪些場景中?怎麼選?
- Nginx應用場景配置Nginx
- FRAM的應用場景
- CDN適用哪些場景?
- Numpy的應用場景
- redis的應用場景Redis
- Vuex 的應用場景Vue