簡述
在java中通常用LinkedBlockingQueue去實(shí)現(xiàn)一個(gè)阻塞隊(duì)列产捞,目的是實(shí)現(xiàn)生產(chǎn)者與消費(fèi)者模型醇锚,該模型是一個(gè)多線程同步問題的經(jīng)典案例哼御,生產(chǎn)者的主要作用是生成一定量的數(shù)據(jù)放到緩沖區(qū)中坯临,然后重復(fù)此過程。與此同時(shí)恋昼,消費(fèi)者也在緩沖區(qū)消耗這些數(shù)據(jù)看靠。該問題的關(guān)鍵就是要保證生產(chǎn)者不會(huì)在緩沖區(qū)滿時(shí)加入數(shù)據(jù),消費(fèi)者也不會(huì)在緩沖區(qū)中空時(shí)消耗數(shù)據(jù)液肌。
在kotlin中同樣也有該實(shí)現(xiàn)挟炬,是通過協(xié)程Channel實(shí)現(xiàn)的,當(dāng)你異步操作的時(shí)候可以通過channel傳遞消息嗦哆。有一點(diǎn)需要知道谤祖,Channel的緩沖去可以是0個(gè),當(dāng)有信息send進(jìn)去后老速,協(xié)程就會(huì)被掛起粥喜,只有被調(diào)receive后才會(huì)繼續(xù)執(zhí)行。
Channel實(shí)現(xiàn)的阻塞隊(duì)列并不是真正的阻塞橘券,而是協(xié)程被掛起额湘,所以這點(diǎn)還是比LinkedBlockingQueue實(shí)現(xiàn)的隊(duì)列要更輕量級。
Demo
下面舉個(gè)官方栗子:
在協(xié)程runBlocking中旁舰,實(shí)例化channel對象锋华,泛型是Int代表要傳遞Int類型的值,在異步協(xié)程launch中循環(huán)發(fā)送箭窜,在接下來的執(zhí)行中repeat 5次打印接受的消息毯焕。
這里可以看出channel有個(gè)特點(diǎn):
它可以在不同協(xié)程中隨意傳遞消息,而且是安全的磺樱。
打印結(jié)果:
再舉個(gè)官方栗子:
channel還有個(gè)特點(diǎn)是阻塞隊(duì)列沒有芥丧,它可以隨時(shí)關(guān)閉,當(dāng)發(fā)送者接收到關(guān)閉指令坊罢,將立即停止發(fā)送续担。
是不是這樣就沒了,每次都要自己new一個(gè)channel活孩,還要for循環(huán)去接收物遇,有點(diǎn)接受不了吧。官方封裝了更加簡單的用法,通過produce實(shí)現(xiàn)询兴,并在接收方通過consumeEach代替for循環(huán)
再++舉個(gè)栗子:
produce在工作線程中send數(shù)據(jù)乃沙,squares通過consumeEach接收。是不是簡單多了诗舰。
總結(jié)
協(xié)程總是以更輕量級警儒,更安全,更高效的方式去解決并發(fā)中的問題眶根,這點(diǎn)很贊蜀铲,而且我們相信kotlin在不久的將來會(huì)是一門很熱門的語言。愿在android的道路上與你攜手到老属百,情人節(jié)快樂记劝。