当前位置:网站首页>Android kotlin collaboration Async
Android kotlin collaboration Async
2022-06-23 15:39:00 【Programmer Xiao He SS】
measureTimeMillis Count the time taken for a piece of code
The function of convergence measureTimeMillis{ } It is very convenient to count the execution time of a piece of code .
Use :
GlobalScope.launch {
val time = measureTimeMillis {
delay(1000)
Log.d("zyj-", " journal ")
}
Log.d("zyj-", " Time consuming :$time")
}Output results :
D/zyj-: journal D/zyj-: Time consuming :1010
Use default order
Define two time-consuming functions :
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // Suppose we do something useful here
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // Suppose we do something useful here
return 29
}Call... In the default order :
val time = measureTimeMillis {
val one = doSomethingUsefulOne()
val two = doSomethingUsefulTwo()
println("The answer is ${one + two}")
}
println("Completed in $time ms")Its printout is as follows :
The answer is 42 Completed in 2017 ms
In terms of output results , The two time-consuming tasks are serial , Total time = Time consuming function 1 + Time consuming function 2
Use async Concurrent
If doSomethingUsefulOne And doSomethingUsefulTwo There is no dependency between , And we want to get results faster , Let them Concurrent Do you ? This is it. async Where we can help .
Conceptually ,async Is similar to the launch. It starts a single process and works concurrently with all other processes . The difference is launch Return to one Job And without any result value , and async Return to one Deferred—— A non blocking future, This represents a result that will be provided later promise. You can use .await() Get its final result on the value of an extension , however Deferred Also a Job, So if you need to , You can cancel it .
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")Its printout is as follows :
The answer is 42 Completed in 1017 ms
It's twice as fast here , Because two coroutines execute concurrently . Please note that , Concurrency using coroutines is always explicit .
Inert start async
Optional ,async It can be done by putting start Parameter set to CoroutineStart.LAZY And become inert . In this mode , Only the result passed await The process will start when it is acquired , Or in Job Of start When the function is called . Run the following example :
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
// Perform some calculations
one.start() // Start the first
two.start() // Start the second
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")Its printout is as follows :
The answer is 42 Completed in 1017 ms
therefore , In the previous example, the two coroutines defined here were not executed , But the control lies in the programmer's exact call at the beginning of execution start. First of all call one, And then call two, Next, wait for the execution of the cooperation process to be completed .
Be careful , If we were just println Call in await, Instead of calling in a separate association. start, This will lead to sequential behavior , until await Start the process Execute and wait until it ends , This is not an inert intended use case . When calculating a value involving a suspended function , This async(start = CoroutineStart.LAZY) Use cases are used to replace those in the standard library lazy function .
structure async Function of style
We can define asynchronous style functions to asynchronous Call to doSomethingUsefulOne and doSomethingUsefulTwo And use async The coroutine builder comes with an explicit GlobalScope quote . We add... To the name of such a function “……Async” Suffix to highlight : in fact , They only do asynchronous calculations and need to use deferred values to get results .
// somethingUsefulOneAsync The return value type of the function is Deferred<Int>
fun somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
// somethingUsefulTwoAsync The return value type of the function is Deferred<Int>
fun somethingUsefulTwoAsync() = GlobalScope.async {
doSomethingUsefulTwo()
}Use
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// We can start asynchronous execution outside of the coroutine
val one = somethingUsefulOneAsync()
val two = somethingUsefulTwoAsync()
// But waiting for the result must call another suspend or block
// When we wait for the result , Here we use `GlobalScope.launch{ }` To block the main thread
GlobalScope.launch {
println("The- answer is ${one.await()} ${two.await()}")
}
}
}This programming style with asynchronous functions is for reference only , Because this is a popular style in other programming languages . stay Kotlin It is strongly not recommended to use this style in the cooperation process of , The reasons are as follows .
Consider if val one = somethingUsefulOneAsync() This line and one.await() The expression here has a logic error in the code , And the program throws an exception and the program aborts during the operation , What's going to happen . Usually , A global exception handler will catch this exception , Print the exception into a journal and report it to the developer , But on the contrary, the program will continue to perform other operations . But here we are somethingUsefulOneAsync Still executing in the background , For all that , The operation that started it will also be terminated . This program will not have structured concurrency , As shown in the following section .
Use async Structured concurrency
Let's use async And extract the concurrent call of a function doSomethingUsefulOne And doSomethingUsefulTwo And return the sum of their two results . because async Defined as CoroutineScope Extension on , We need to write it in scope , And this is coroutineScope Provided by the function :
suspend fun concurrentSum(): Int = coroutineScope {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
one.await() + two.await()
}In this case , If in concurrentSum There is an error inside the function , And it throws an exception , All coroutines started in the scope are canceled .
val time = measureTimeMillis {
println("The answer is ${concurrentSum()}")
}
println("Completed in $time ms")From the above main The output of the function shows that , We can still perform both operations at the same time :
The answer is 42 Completed in 1017 ms
Cancel always passing through the hierarchy of the collaboration :
import kotlinx.coroutines.*
fun main() = runBlocking<Unit> {
try {
failedConcurrentSum()
} catch(e: ArithmeticException) {
println("Computation failed with ArithmeticException")
}
}
suspend fun failedConcurrentSum(): Int = coroutineScope {
val one = async<Int> {
try {
delay(Long.MAX_VALUE) // Simulate a long operation
42
} finally {
println("First child was cancelled")
}
}
val two = async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}
one.await() + two.await()
}Please note that , If one of the subprocesses ( namely two) Failure , first async And the waiting parent process will be cancelled :
Second child throws an exception First child was cancelled Computation failed with ArithmeticException
边栏推荐
- Important knowledge of golang: rwmutex read / write lock analysis
- Volatile~ variables are not visible under multithreading
- Horizon development board commissioning
- Sorting out and summarizing the handling schemes for the three major exceptions of redis cache
- 聚合生态,使能安全运营,华为云安全云脑智护业务安全
- [普通物理] 光的衍射
- golang 重要知识:sync.Cond 机制
- Xampp中mysql无法启动问题的解决方法
- 2021-06-07
- 力扣解法汇总513-找树左下角的值
猜你喜欢
Redis缓存三大异常的处理方案梳理总结

golang 重要知识:sync.Once 讲解

MySQL create and manage tables

golang 重要知识:定时器 timer

他山之石 | 微信搜一搜中的智能问答技术

Gartner最新报告:低代码应用开发平台在国内的发展

The work and development steps that must be done in the early stage of the development of the source code of the live broadcasting room

自监督学习(SSL)Self-Supervised Learning

JS traversal array (using the foreach () method)
![[MAE]Masked Autoencoders掩膜自编码器](/img/08/5ab2b0d5b81c723919046699bb6f6d.png)
[MAE]Masked Autoencoders掩膜自编码器
随机推荐
php 二维数组插入
电子学会图形化一级编程题解析:猫捉老鼠
golang 重要知识:sync.Cond 机制
JS中的pop()元素
FPN特征金字塔网络
[cloud based co creation] intelligent supply chain plan: improve the decision-making level of the supply chain and help enterprises reduce costs and increase efficiency
Arrays in JS
[datahub] LinkedIn datahub learning notes
General sequence representation learning in kdd'22 "Ali" recommendation system
Simple tutorial of live streaming with OBS
Thymeleaf——学习笔记
Simple understanding of quick sort
Important knowledge of golang: waitgroup parsing
The work and development steps that must be done in the early stage of the development of the source code of the live broadcasting room
golang 重要知识:context 详解
golang 重要知识:atomic 原子操作
Convert JSON file of labelme to coco dataset format
Important knowledge of golang: timer timer
他山之石 | 微信搜一搜中的智能问答技术
Pop() element in JS