協程: 是一種更爲靈活高效的"用戶線程",可以選擇異步仍是同步執行,指定運行的線程。編程
異步、同步編程 : 是指的協程可以選擇自身的啓動模式,在當前線程堵塞式運行,仍是在後臺線程異步執行;bash
指定運行線程:可以方便的選擇執行的線程是後臺線程仍是UI主線程;微信
在併發處理上會比使用線程來得更加的高效。併發
進程 > 線程 > 協程, 即一個進程能夠包含多個線程,一個線程上面能夠運行多個協程。異步
目前從非協程環境中啓動協程環境主要有三種方式async
啓動方式 | 說明 |
---|---|
runBlocking | 建立新的協程,運行在當前線程上,因此會堵塞當前線程,直到協程體結束 |
GlobalScope.launch | 啓動一個新的線程,在新線程上建立運行協程,不堵塞當前線程 |
GlobalScope.asyn | 啓動一個新的線程,在新線程上建立運行協程,而且不堵塞當前線程,支持 經過await獲取返回值 |
建立新的協程運行在當前線程上,因此會堵塞當前線程,直到協程體結束ui
用於啓動一個協程任務,一般只用於啓動最外層的協程,例如線程環境切換到協程環境spa
/**
* runBlocking建立新的協程運行在當前線程上,因此會堵塞當前線程,直到協程體結束
*
* 適用範圍: 用於啓動一個協程任務,一般只用於啓動最外層的協程,例如線程環境切換到協程環境。
*
* 打印出:
* current thread = main,1
* runBlocking thread = main @coroutine#1,1
* runBlocking end
* current thread end
*/
@Test
fun runBlockingTest() {
println("current thread = ${Thread.currentThread().name},${Thread.currentThread().id}")
//runBlocking運行在當前線程上,堵塞當前線程
runBlocking {
println("runBlocking thread = ${Thread.currentThread().name},${Thread.currentThread().id}")
delay(1000)
println("runBlocking end")
}
//等待runBlocking協程體內的內容執行完畢,才繼續執行
println("current thread end")
}
複製代碼
建立新的協程,默認運行在後臺新的線程中,而且不堵塞當前線程線程
適用範圍: 須要啓動異步線程處理的狀況code
/**
* GlobalScope.launch默認運行在後臺新的調度線程中,而且不堵塞當前線程
*
* 適用範圍: 須要啓動異步線程處理的狀況
*
* 輸出:
* current thread = main, 1
* current thread end
* launch thread = DefaultDispatcher-worker-2 @coroutine#1, 12
* launch thread end
*/
@Test
fun launchTest() {
println("current thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
//launch啓動後臺調度線程,而且不堵塞當前線程
GlobalScope.launch {
println("launch thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
delay(1000)
println("launch thread end")
}
println("current thread end")
//當前線程休眠以便調度線程有機會執行
Thread.sleep(3000)
}
複製代碼
建立新的協程,默認運行在後臺新的線程中,而且不堵塞當前線程,支持經過await獲取返回值
GlobalScope.async與GlobalScope.launch大體相同,
區別: 1.async返回類型爲Deferred, launch返回類型爲job 2.async能夠在協程體中自定義返回值,而且經過Deferred.await堵塞當前線程等待接收async協程返回的類型。
特別是須要啓動異步線程處理並等待處理結果返回的場景
/**
* async與launch的相同點:都是不堵塞當前線程並啓動後臺調度線程。
* 區別: 1.async返回類型爲Deferred, launch返回類型爲job
* 2.async能夠在協程體中存在自定義的返回值,而且經過Deferred.await堵塞當前線程等待接收async協程返回的類型。
*
* 適用範圍: 特別是須要啓動異步線程處理並等待處理結果返回的場景
*
* 打印出:
* current thread = main @coroutine#1, 1
* current thread end
* async thread = DefaultDispatcher-worker-1 @coroutine#2, 11
* async end
* result = 123
*/
@Test
fun asyncTest() {
runBlocking {
println("current thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
//launch啓動後臺調度線程,而且不堵塞當前線程
val deferred = GlobalScope.async {
println("async thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
delay(1000)
println("async end")
//須要經過標籤的方式返回
return@async "123"
}
println("current thread end")
val result = deferred.await()
println("result = $result")
//當前線程休眠以便調度線程有機會執行
Thread.sleep(3000)
}
}
複製代碼
目前從非協程環境中啓動協程環境主要有三種方式
啓動方式 | 說明 |
---|---|
runBlocking | 建立新的協程,運行在當前線程上,因此會堵塞當前線程,直到協程體結束 |
GlobalScope.launch | 啓動一個新的線程,在新線程上建立運行協程,不堵塞當前線程 |
GlobalScope.asyn | 啓動一個新的線程,在新線程上建立運行協程,而且不堵塞當前線程,支持 經過await獲取返回值 |
建立新的協程運行在當前線程上,因此會堵塞當前線程,直到協程體結束
用於啓動一個協程任務,一般只用於啓動最外層的協程,例如線程環境切換到協程環境
/**
* runBlocking建立新的協程運行在當前線程上,因此會堵塞當前線程,直到協程體結束
*
* 適用範圍: 用於啓動一個協程任務,一般只用於啓動最外層的協程,例如線程環境切換到協程環境。
*
* 打印出:
* current thread = main,1
* runBlocking thread = main @coroutine#1,1
* runBlocking end
* current thread end
*/
@Test
fun runBlockingTest() {
println("current thread = ${Thread.currentThread().name},${Thread.currentThread().id}")
//runBlocking運行在當前線程上,堵塞當前線程
runBlocking {
println("runBlocking thread = ${Thread.currentThread().name},${Thread.currentThread().id}")
delay(1000)
println("runBlocking end")
}
//等待runBlocking協程體內的內容執行完畢,才繼續執行
println("current thread end")
}
複製代碼
建立新的協程,默認運行在後臺新的線程中,而且不堵塞當前線程
適用範圍: 須要啓動異步線程處理的狀況
/**
* GlobalScope.launch默認運行在後臺新的調度線程中,而且不堵塞當前線程
*
* 適用範圍: 須要啓動異步線程處理的狀況
*
* 輸出:
* current thread = main, 1
* current thread end
* launch thread = DefaultDispatcher-worker-2 @coroutine#1, 12
* launch thread end
*/
@Test
fun launchTest() {
println("current thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
//launch啓動後臺調度線程,而且不堵塞當前線程
GlobalScope.launch {
println("launch thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
delay(1000)
println("launch thread end")
}
println("current thread end")
//當前線程休眠以便調度線程有機會執行
Thread.sleep(3000)
}
複製代碼
建立新的協程,默認運行在後臺新的線程中,而且不堵塞當前線程,支持經過await獲取返回值
GlobalScope.async與GlobalScope.launch大體相同,
區別: 1.async返回類型爲Deferred, launch返回類型爲job 2.async能夠在協程體中自定義返回值,而且經過Deferred.await堵塞當前線程等待接收async協程返回的類型。
特別是須要啓動異步線程處理並等待處理結果返回的場景
/**
* async與launch的相同點:都是不堵塞當前線程並啓動後臺調度線程。
* 區別: 1.async返回類型爲Deferred, launch返回類型爲job
* 2.async能夠在協程體中存在自定義的返回值,而且經過Deferred.await堵塞當前線程等待接收async協程返回的類型。
*
* 適用範圍: 特別是須要啓動異步線程處理並等待處理結果返回的場景
*
* 打印出:
* current thread = main @coroutine#1, 1
* current thread end
* async thread = DefaultDispatcher-worker-1 @coroutine#2, 11
* async end
* result = 123
*/
@Test
fun asyncTest() {
runBlocking {
println("current thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
//launch啓動後臺調度線程,而且不堵塞當前線程
val deferred = GlobalScope.async {
println("async thread = ${Thread.currentThread().name}, ${Thread.currentThread().id}")
delay(1000)
println("async end")
//須要經過標籤的方式返回
return@async "123"
}
println("current thread end")
val result = deferred.await()
println("result = $result")
//當前線程休眠以便調度線程有機會執行
Thread.sleep(3000)
}
}
複製代碼