過(guò)年后凤类,懶惰小人總是能夠輕而易舉地?fù)魯∧莻€(gè)可憐的勤奮小人穗泵,轉(zhuǎn)眼間又有好幾周沒(méi)有寫(xiě)文章了。愧疚感滿滿谜疤,作出檢討佃延,主要原因:
第一现诀,工作忙,重構(gòu)任務(wù)重履肃;
第二仔沿,人到中年,開(kāi)始養(yǎng)生尺棋,沒(méi)想到這還真是一個(gè)需要花時(shí)間的事情封锉。??
第三,有時(shí)會(huì)去偷看《風(fēng)味人間》和《圓桌派》膘螟,怪我咯成福!誰(shuí)叫人家的節(jié)目做的那么好看。
接著荆残,分享一個(gè)最近看文章養(yǎng)成的習(xí)慣:
第一奴艾,先大體掃讀一遍,看看評(píng)論好壞和文章排版脊阴,基本上就能知道這篇文章講的水平與深度是否值得去讀握侧;
第二,接著一字一句慢慢讀嘿期,不要求快品擎,容易遺漏關(guān)鍵信息。
第三备徐,變讀邊想萄传,由文章所描述的內(nèi)容可以推出什么其他信息或問(wèn)題。
好了蜜猾,言歸正傳秀菱。今天在學(xué)習(xí)網(wǎng)絡(luò)編程時(shí),接觸到一個(gè)類(lèi)蹭睡,計(jì)數(shù)鎖CountDownLatch
類(lèi)衍菱,以前竟然沒(méi)有發(fā)現(xiàn)這個(gè)這么好用的同步工具類(lèi),還自己去傻傻的實(shí)現(xiàn)過(guò)同樣的功能肩豁。
1 簡(jiǎn)介
對(duì)于這個(gè)類(lèi)脊串,最常用的場(chǎng)景就是等待前面n個(gè)任務(wù)完成,然后再去執(zhí)行另外一個(gè)任務(wù)清钥。
這個(gè)場(chǎng)景琼锋,用在我們項(xiàng)目中的接口上最合適不過(guò)了,我們的APP中同一個(gè)頁(yè)面經(jīng)常需要調(diào)用好幾個(gè)接口去拼裝數(shù)據(jù)祟昭。把這些接口串聯(lián)起來(lái)有可能因?yàn)槠渲械囊粋€(gè)接口出現(xiàn)異常而導(dǎo)致數(shù)據(jù)刷新失敗缕坎。回來(lái)一個(gè)接口就去刷新一個(gè)數(shù)據(jù)總顯得又不是那么優(yōu)雅篡悟。
2 CountDownLatch的使用
而CountDownLatch的使用將很方便的解決上述問(wèn)題谜叹,我們一起來(lái)看看匾寝。
初始化CountDownLatch,2為內(nèi)部的計(jì)數(shù)值叉谜,代表可以調(diào)用幾次countDown()方法旗吁。每次調(diào)用都會(huì)遞減內(nèi)部的計(jì)數(shù)值踩萎,當(dāng)為0時(shí)停局,await()方法所等待的線程將被喚醒。
初始化
CountDownLatch latch = new CountDownLatch(2);
計(jì)數(shù)值減1
latch.countDown();
讓某個(gè)線程進(jìn)行等待香府,直到計(jì)數(shù)值變成0為止董栽。
latch.await();
接著我們上代碼。
CountDownLatch latch = new CountDownLatch(2);
CheckThread checkNet = new CheckThread("net", latch);
CheckThread checkApp = new CheckThread("app", latch);
new Thread(() -> {
System.out.println("await thread is begin!");
try {
latch.await();
System.out.println("await thread is done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
checkApp.start();
checkNet.start();
class CheckThread extends Thread {
private String name;
private CountDownLatch latch;
CheckThread(String name, CountDownLatch latch) {
this.name = name;
this.latch = latch;
}
@Override
public void run() {
super.run();
System.out.println("任務(wù)" + name + "開(kāi)始運(yùn)行");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (latch != null) {
latch.countDown();
}
}
System.out.println("任務(wù)" + name + "完成");
}
}
我們初始化了兩個(gè)線程checkNet企孩,checkApp去執(zhí)行耗時(shí)任務(wù)锭碳,當(dāng)任務(wù)結(jié)束時(shí),我們調(diào)用countDown()
方法表示該條線程處的任務(wù)執(zhí)行完畢勿璃。
我們可以把線程checkNet擒抛,checkApp分別看成接口A和接口B去請(qǐng)求數(shù)據(jù),而new Thread()
產(chǎn)生的線程則一直在等待其他兩條線程執(zhí)行結(jié)束补疑,如果結(jié)束歧沪,new Thread()
線程將被喚醒,繼續(xù)執(zhí)行余下的邏輯莲组。
這里的new Thread()
線程的開(kāi)啟是為了在Android中不阻塞主線程诊胞,它的等待也可以用如下方式設(shè)置最多等到多久
latch.await(10, TimeUnit.SECONDS);
以免某個(gè)線程沒(méi)有正確返回導(dǎo)致一直處于等待中。
最終打印的結(jié)果如下
await thread is begin!
任務(wù)app開(kāi)始運(yùn)行
任務(wù)net開(kāi)始運(yùn)行
任務(wù)net完成
任務(wù)app完成
await thread is done!
Process finished with exit code 0
歡迎留言交流锹杈,如果覺(jué)得有用撵孤,請(qǐng)點(diǎn)贊支持!