当前位置:网站首页>Deep understanding of continuation principle
Deep understanding of continuation principle
2022-06-30 09:02:00 【Byte station】
1. Preface
This is the first update since the new year , I'd like to give you a good old age , I wish you all the best in the new year , At the same time, thank you for your continuous support and help . This article was actually conceived before the Spring Festival , I wanted to finish it during the Chinese New Year in Beijing , Due to plan change , I went back to my hometown for the Spring Festival , During the Spring Festival, I spent most of my time visiting relatives , The article was shelved .
Gossip and less narration , In this article, I will try to make it clear to you ,Kotlin How to realize asynchronous calling in a synchronous way . I believe many students can say one or more of the following concepts .
- Kotlin suspend keyword
- Kotlin Inside Continuation Mechanism
- Continuation Passing Style (CPS) Mechanism
- Finite state machine mechanism
If you've seen it Kotlin Collaborative architects Deep dive into Coroutines on JVM Speech Video , I believe you will not be unfamiliar with the above concepts .
Video link https://www.youtube.com/watch?v=YrrUCSi72E8&t=1329s
But if you don't delve into the source code to see how it works , I believe you know a little about the above concepts . This article will lead you to a more detailed understanding of this knowledge .
2. A step-by-step example
Suppose there is such a simple scenario , stay App Make a request on ,10s Get the response after , Update to the user interface . We may encounter the following expressions .
2.1 Call directly on the main thread

This situation , Everybody knows that , For client development , It is absolutely impossible to perform time-consuming operations on the main thread . In order not to block the main thread , We need to start a new thread , Using callbacks , Send back the results .
2.2 Use callback

This way, , Although it solves the problem of time-consuming operation in the main thread , But it introduces new problems , Update in child thread UI, Will cause the application to crash . To solve this problem , We need to go through the main thread Handler, hold callback post Run to the main thread .
2.3 Use callback and handler Combine

So far, , We use threads , Callback ,Handler combination , A perfect implementation for executing an asynchronous request , And update the results to UI On .
There are three elements in this scheme :
1. Thread or thread pool technology
2. Callback mechanism , Feed the result back to the caller
3. The thread in which the callback operation is executed
So here we should hit the blackboard to draw the key points
Since this article is about cooperative process , So which classes in the collaboration process correspond to these three elements respectively ?
Dispatchers.Main、Dispatchers.IO Equivalent thread
Continuation Corresponding to the callback in the thread
DispatchedContinuation It also specifies Continuation Callback , It also specifies the thread in which the callback is executed .
Let's not start here Continuation and DispatchedContinuation Specific details of , Make a cushion here , I'll explain it in detail later .
2.4 Use a coroutine to implement

This code is the correct code for the coprocessor implementation , There are no time-consuming operations performed by the main thread , No child thread updates UI problem . Of course, there is no explicit callback, And thread switching code . Only right suspendHeavyWork Methods added suspend keyword , You can call asynchronously Using synchronized code . So where is the magic ?
3. Magic uncover
First, post the full version of the code 
Use Android Studio Of Show Kotlin Bytecode Function to view decompiled files 
Sigh with emotion x1 Read the decompiled code , You may need to sigh , There is no time to be quiet , It's just that someone is carrying a load for you . Writing code with coprocessor , Because the compiler did a lot of work later , Understand the work behind this , It is very helpful for us to use the cooperative process .
confused x1 So the code generated by the compiler , Looks familiar and strange , It is said that we are familiar with each line of code in terms of syntax (switch case I'm familiar with them ), I say strange because in general , I don't quite understand what they did , There are even functions ( such as invokeSuspend) I don't even know where to call .
confused x2 What's more confusing is , In the state machine code return sentence , How does the following code execute ? To understand the principle of state machine, we must understand this problem .
4. Research launch Decompile

The top icon shows three important places .
lambda The expression is converted to Function2 example , that Function2 What is it? ? Why did you give me Function2 Passed a type of Continuation Of null object ?
invokeSuspend What is the method ? Note that the parameter is not empty .
call heavyWork(this) Into this object . As we can see from the above ,heavyWork After decompiling, the method becomes heavyWork(Continuation var). It means that Function2 yes Continuation type .
With the above questions , Then the answer is not far away .
4.1 invokeSuspend
First answer the simplest question ,invokeSuspend What is the method . It is defined in BaseContinuationImpl Class , It's an abstract method .


from BaseContinuationImpl(public val completion:Continuation<Any?>?) We can know that the callbacks in the collaboration are linked by a linked list .
Suppose there is suspend The function call is as follows , that Continuation The diagram is as follows .


- First one while loop , It ensures that the state machine can poll .
- val completion = completion!! If at present Continuation There is no callback on the left , Come back quickly
- val outcome = invokeSuspend(param) Call current Continuation Of invokeSuspend Method
- If outcome === COROUTINE_SUSPENDED Go straight back to . That's why delay Method does not block the current thread , encounter suspend Method label Meeting +1, At present Continuation Will pass to delay.
- if (completion is BaseContinuationImpl) Continue to call recursively invokeSuspend
- Otherwise, call completion.resumeWith(outcome) And back to
This code is the core to ensure that the state machine can run .
4.2 Function2 What is it? ?
Function2 yes SuspendLambda, It's defined in ContinuationImpl.kt in . It is BaseContinuationImpl Subclasses of .
5. DispatchedContinuation
internal class DispatchedContinuation<in T>(
@JvmField val dispatcher: CoroutineDispatcher,
@JvmField val continuation: Continuation<T>
)
DispatchedContinuation Yes dispatcher and continuation Two member variables . It means that dispatcher The corresponding thread , perform continuation Callback . When a thread switch occurs , Will certainly generate DispatchedContinuation object , otherwise , After cutting the thread , You can't cut it back .
for example delay and withContext, After switching threads, it will create DispatchedContinuation, To record the thread on which the callback will be called .


Welcome to your attention " Byte station " The official account of the same name !!
Welcome to your attention " Byte station " The official account of the same name !!
Welcome to your attention " Byte station " The official account of the same name !!
边栏推荐
- Esp32 (6): Bluetooth and WiFi functions for function development
- Rew acoustic test (V): equipment required for test
- Mmdet line by line deltaxywhbboxcoder
- Sort (simple description)
- Esp32 things (V): analysis of common API of esp32 of Swiss Army knife
- Flink SQL custom connector
- Redis design and Implementation (II) | database (deletion strategy & expiration elimination strategy)
- CUDA realizes matrix multiplication
- Unsupportedclassversionerror is reported when starting jar package. How to repair it
- [paid promotion] collection of frequently asked questions, FAQ of recommended list
猜你喜欢

Flink Exception -- No ExecutorFactory found to execute the application

Duplicate entry '2' for key 'primary appears in JPA‘

C#访问MongoDB并执行CRUD操作

Interviewer: do you understand the principle of recyclerview layout animation?

Interpretation of orientedrcnn papers

Esp32 things (II): sharpening the knife without mistaking firewood - make preparations before project development

Explanation on the use of password profiteering cracking tool Hydra

Based on svelte3 X desktop UI component library svelte UI

Use Huawei performance management service to configure the sampling rate on demand

asdsadadsad
随机推荐
Using appbarlayout to realize secondary ceiling function
Rew acoustic test (V): equipment required for test
[protobuf] protobuf generates cc/h file through proto file
Do you want the dialog box that pops up from the click?
Raspberry pie 4B no screen installation system and networking using VNC wireless projection function
vim 从嫌弃到依赖(21)——跨文件搜索
How to format an UTC date to use the Z (Zulu) zone designator in php?
Esp32 (IX): OTA function of function development
将线程绑定在某个具体的CPU逻辑内核上运行
14岁懂社会-《关于“工作的幸福”这件事儿》读书笔记
Design specification for smart speakers v1.0
Redis design and Implementation (IV) | master-slave replication
mysql基础入门 day3 动力节点[老杜]课堂笔记
Opencv learning notes -day10 logical operation of image pixels (usage of rectangle function and rect function and bit related operation in openCV)
Redis design and Implementation (II) | database (deletion strategy & expiration elimination strategy)
【付费推广】常见问题合集,推荐榜单FAQ
icon资源
Icon resources
[untitled]
Flink Exception -- No ExecutorFactory found to execute the application