###### tags: `Concurrency` `Kotlin` {%hackmd BPS70ijYRAKtBg90J9y3_Q %} # [影片筆記] [扔物线](https://www.youtube.com/@rengwuxian):協程相關教學 [TOC] ## [Kotlin 的协程「用力瞥一眼」](https://www.youtube.com/watch?v=LKsGkEsEE7w) :::info :information_source: **協程的底層實現還是執行緒池,畢竟如果真的有這麼神奇,Java 這些年難道都不知道?** ::: 協程其實就是 Kotlin 提供的執行緒 API:它可以 - 讓我們以看似同步的語法寫出非同步的程式碼,而不需要過度關心執行緒本身。 - 將多層的回呼 (Callback) 函式抹平為單層的非同步程式碼,這是一個「質變」的改進。 在回呼函式中,非同步這件事是很難做到的,故開發者會妥協而將程式碼同步化,而這便犧牲了執行效率。有了協程,非同步變得輕鬆寫意:執行緒想怎麼切就怎麼切,我們只需要合併最後的結果。 舉例來說, ```kotlin= launch(Dispatchers.IO) { // ... launch(Dispatchers.Main) { // ... launch(Dispatchers.IO) { // ... launch(Dispatchers.Main) { // ... ``` 的回呼形式現在可以直接攤平為 ```kotlin= launch(Dispachers.IO) { // ... withContext(Dispatchers.Main) { // ... // ... WithContext(Dispatchers.Main) { // ... ``` ## [Kotlin 协程的挂起好神奇好难懂?今天我把它的皮给扒了](https://www.youtube.com/watch?v=mDtXcEuOXvk) 所謂的 `suspend` 就是指協程 (也就是 `launch` 或 `async` 裡的程式碼) 被暫停了。但是與其譯作暫停,不如用「脫離」這個字眼會更好:協程只是從目前的執行緒脫離,而並非是真的停止了。 因此我們有兩件事需要釐清: - 如何處理閒置的執行緒? - 脫離後的協程會到哪裡? 第一個問題的答案就跟執行緒池的處理一樣 (畢竟本質一模一樣),這個執行緒要嘛做其它事,要嘛被回收掉;而脫離的協程會在暫停函式指定的執行緒中執行,待函式結束後再依照調度器的種類,決定是否切回原執行緒:Kotlin 把「切回來」這件事叫做 Resume。 而協程也並不是一進入另一個暫停函式時,就從原執行緒脫離:這件事是遇到 `withContext()` 才發生的。創建暫停函式的目的與其它的函式都一樣:降低程式碼的重複性、增加程式碼的可讀性。 總結來說,創造 `suspend` 這個關鍵字並不是為了直接處理協程,而是要讓函式創建者提醒、警示調用者:現在要使用的函式很花時間,所以必須放在後臺執行,因此你需要在協程中呼叫這個函式。 ## [到底什么是「非阻塞式」挂起?协程真的比线程更轻量级吗?](https://www.youtube.com/watch?v=NnLQ9zvrcCo) 所謂「非阻塞式」就是「不卡執行緒」的意思:所有的程式碼在本質上都是阻塞式的,只是它們通常都不耗時,導致我們察覺不出來。另外,協程本質上就是一個切執行緒的 API,沒什麼特別的魔法。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up