当前位置:网站首页>Kotlin collaboration - start and cancel, scope
Kotlin collaboration - start and cancel, scope
2022-06-13 06:26:00 【m0_ forty-seven million nine hundred and fourteen thousand one 】
One . The start of the process
1. Coroutine builder
launch And async Builders are used to start new processes :
launch, Return to one Job And without any result value .
async, Return to one Deferred,Deferred Also a job, have access to await Get its final result on the value of an extension .
fun main() {
testCoroutine();
}
// runBlocking Main process He will wait until the task of the sub coordination process is completed , Before that, it was blocked
fun testCoroutine()= runBlocking {
//async Of await Function will delay the return of a result value ,launch You can't
val job = launch {
delay(2000)
println( "launch finished")
}
val job1 = async {
delay(2000)
println( "async finished")
"async result"
}
println(job1.await())
}Print the results :
launch finished
async finished
async result2.launch And async Sequential execution
We often encounter such a situation , Call one interface to get information, and then call other interfaces , In this way, call in order .
1.launch
fun main() {
testCoroutine1();
}
//runBlocking Main process He will wait until the task of the sub coordination process is completed , Before that, it was blocked
fun testCoroutine1()= runBlocking {
// All asynchronous tasks
val launch = launch {
delay(100)
println("One")
}
//join Is a suspend function He will pause until all the tasks are completed
launch.join()
val launch1 = launch {
delay(100)
println("Two")
}
val launch2 = launch {
delay(100)
println("Three")
}
}Print the results :
One
Two
Three2.async
fun main() {
testCoroutine1();
}
//runBlocking Main process He will wait until the task of the sub coordination process is completed , Before that, it was blocked
fun testCoroutine1()= runBlocking {
val async = async {
delay(100)
println("One")
}
async.await()
val async1 = async {
delay(100)
println("Two")
}
val async2 = async {
delay(100)
println("Three")
}
}Print the results :
One
Two
Three3.async Structured concurrency
fun main() {
TestSync()
}
//runBlocking Main process He will wait until the task of the sub coordination process is completed , Before that, it was blocked
fun TestSync()= runBlocking {
val time = measureTimeMillis {
// In this way, two subprocesses can be started to execute concurrent tasks at the same time
val doOne = async {doOne() }
val doTwo = async {doTwo() }
// Here, the operation is performed after all the called synchronization methods are executed
print("The result:${doOne.await() + doTwo.await()} \n")
}
print("Completed in $time ms")
}
suspend fun doOne():Int {
delay(1000)
return 20
}
suspend fun doTwo():Int {
delay(1000)
return 25
}Print the results
The result:45
Completed in 1027 msHere we can see that I delay each of the two functions that get values 1 second , However, due to structural concurrency, the execution time of the whole method is only one second .
4. The startup mode of the coroutine
DEFAULT: After the collaboration is created , Start scheduling immediately , If the collaboration is cancelled before scheduling , It will go directly to cancel
Status of the response .
fun testStartMode() = runBlocking<Unit> {
val job = launch(start = CoroutineStart.DEFAULT) {
var i = 0
while (true){
i++
}
println("finished.")
}
delay(1000)
job.cancel()
}
ATOMIC: After the collaboration is created , Start scheduling immediately , The coroutine does not respond to cancellation until it reaches the first hang point .
fun testStartMode() = runBlocking<Unit> {
val job = launch(start = CoroutineStart.ATOMIC) {
//....
// Canceling is not valid until the first hang point is reached
delay(1000)
println("finished.")
}
}LAZY: Only when collaboration is needed , Including the method of actively calling the coroutine start、join perhaps await Wait for the function to start
Dispatch , If it is cancelled before scheduling , Then the collaboration will directly enter the abnormal end state .
fun testStartMode() = runBlocking<Unit> {
// Inert start
val job = async (start = CoroutineStart.LAZY) {
29
}
// Perform some calculations
// Restart
job.start()
}UNDISPATCHED: After the collaboration is created Immediately execute in the current function call stack , Until the first real hang
fun testStartMode() = runBlocking<Unit> {
// In which thread ?
val job = launch(context = Dispatchers.IO, start = CoroutineStart.UNDISPATCHED) {
println("thread:"+Thread.currentThread().name)
}
}UNDISPATCHED start-up The mode will immediately execute on the current thread , It is possible to execute in the main thread .
5. Process scope
// Scope builder
//runBlocking It's a regular function , and coroutineScope It's a suspend function .
// They look very similar , They all wait for the end of their coroutine body and all child coroutines .
// The main difference is that runBlocking Method blocks the current thread to wait , and coroutineScope Just hang up , The underlying thread is freed for other purposes .
fun testCoroutineScope () = runBlocking {
// Scope builder This inherits the parent scope Context also inherits
//coroutineScope
// A collaboration failed , All other brotherhood programs will also be cancelled
coroutineScope {
val job1 = launch {
delay(400)
println("job1 finished.")
}
val job2 = launch {
delay(200)
println("job2 finished.")
throw IllegalArgumentException()
}
}
//supervisorScope
// A collaboration failed , It won't affect other brothers' cooperation
supervisorScope {
val job1 = launch {
delay(400)
println("job1 finished.")
}
val job2 = launch {
delay(200)
println("job2 finished.")
throw IllegalArgumentException()
}
}
// This is because we inherited runBlocking Scope of action coroutineScope and supervisorScope After the execution runBlocking Will complete
}6.Job Object lifecycle
For each collaboration created ( adopt launch perhaps async), Will return a Job example , This instance is the unique identifier of the collaboration , And manage the lifecycle of the collaboration .
A task can contain a series of States :
New creation (New)、 active (Active)、 Finishing (Completing)、 Completed (Completed)、 Cancel (Cancelling) and Cancelled (Cancelled).
Although we don't have direct access to these States , But we can visit Job Properties of :isActive、isCancelled and isCompleted.
If the process is active , The coroutine runs in error or calls job.cancel() Will set the current task to cancel (Cancelling) state (isActive = false, isCancelled = true).
When all the subprocesses are finished , The program will enter the canceled program (Cancelled) state , here isCompleted = true.
Two . Cancel the program
1. Cancellation of the agreement
1. Canceling the scope cancels its child threads
fun testScopeCancel()= runBlocking {
/* Here, a collaboration scope is created , New context , The following two subprocesses do not count runBlocking
It's the son of Xie Cheng , So in the following, if you do not delay the execution of the program, you can close it */
val scope= CoroutineScope(Dispatchers.Default)
scope.launch {
delay(1000)
print("job 1")
}
scope.launch {
delay(1000)
print("job 2")
}
delay(100)
//scope Scope object As soon as he cancels the subprocess in the scope
scope.cancel()
delay(2000)
}CoroutineScope(Dispatchers.Default) And coroutineScope The difference is that The former has its own scope and context , and coroutineScope It inherits the scope and context of the parent collaboration
2. The rest of the process will not be affected
fun testScopeCancel()= runBlocking {
/* Here, a collaboration scope is created , New context , The following two subprocesses do not count runBlocking It's the son of Xie Cheng ,
So in the following, if you do not delay the execution of the program, you can close it */
val scope= CoroutineScope(Dispatchers.Default)
val launch = scope.launch {
delay(1000)
print("job 1")
}
scope.launch {
delay(1000)
print("job 2")
}
delay(100)
// The cancellation of a subprocess will not affect other subprocesses
launch.cancel()
delay(2000)
}3. Throw an exception to interrupt the coroutine
fun main() {
testCancellationException()
}
fun testCancellationException()= runBlocking {
val launch = GlobalScope.launch {
try {
// This is cancelled because of the cooperation process , It throws an exception
delay(1000)
print("job 1")
}catch (e :Exception){
e.printStackTrace()
}
}
launch.cancel()
//launch .cancel(CancellationException(" Cancel ")) You can also throw an exception here
// Can let runBlocking wait for GlobalScope.launch completion of enforcement
launch.join()
}Abnormal printing :
kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@306b9c532.CPU Intensive tasks are cancelled
//CPU The concurrence of intensive operations cannot be cancelled , You can use the lifecycle of a coroutine to cancel the operation after it stops
fun testCancelCpuTaskByIsActive()= runBlocking{
val startTime = System.currentTimeMillis()
val launch = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0;
//yield Will throw an exception , There will also be a transfer of part of the executive power ( Even if you sell the resources of the thread , But that doesn't mean he won't do it anymore , He will still be performing )
// If the task to be processed belongs to :
//1) CPU intensive ,2) Thread pool resources may be exhausted ,3) You need to allow threads without adding more threads to the thread pool Process other tasks , Then please use yield().
//yield()
//ensureActive() This method is to throw an exception to end the process If job It's inactive , This method will immediately throw an exception .
//ensureActive()
// isActive Is one that can be used in CoroutineScope Extended properties in , Check Job Is it active or not .
// When the coroutine calls cancel When the method is used isActive by false The operation stops
while (i < 5 && isActive) {
if (System.currentTimeMillis() >= nextPrintTime) {
println("job:I'm sleeping ${i++}")
nextPrintTime += 500
}
}
}
delay(1500)
println("main: I'm tired of waiting!")
launch.cancelAndJoin()
println("main: Now I can quit.")
}3. Release resources after the collaboration is cancelled
1. adopt finally Release resources
// stay finally Release resources in
fun testReleaseResources() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
println("job: I'm running finally")
}
}
delay(1300L) // Delay ⼀ Period of time
println("main: I'm tired of waiting!")
job.cancelAndJoin() // Cancel the job and wait for it to finish
println("main: Now I can quit.")
}2.use function
//use function : This function can only be implemented Closeable Object using , When the program ends, it will automatically call close Method , Suitable for file objects
fun testReleaseResources() = runBlocking {
BufferedReader(FileReader("D:\\I have a dream.txt")).use {
var line: String?
while (true) {
line = it.readLine() ?: break // Read a row of data , If it is empty, exit the loop
println(line) // Print the read data
}
}
}4. stay finally Execute the task after the collaboration process is interrupted
fun testReleaseResources() = runBlocking {
val launch = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
// After the general coordination process is cancelled finally The task in will not continue
} finally {
// After the execution of the collaboration process, you can finally Release resources
println("job: I'm running finally")
// Only in this way can we cancel the process and continue finally The task of It can also be used in the coordination process
withContext(NonCancellable){
println("job: I'm running finally")
delay(1000L)
println("Job:And I've just delayed for 1 sec because I'm non-cancellable")
}
}
}
}5. Processing timeout tasks
fun main() {
testDealWithTimeout()
}
fun testDealWithTimeout()= runBlocking{
// Handle time-consuming tasks in this way
// exceed 1300 The task timed out in milliseconds
val withTimeout = withTimeoutOrNull(1300) {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
"Done"
}?:"Jack"
// Execution successful return Done Timeout returns Jack
println("Result is $withTimeout ...")
}边栏推荐
- App performance test: (III) traffic monitoring
- ‘ipconfig‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
- Kotlin basic objects, classes and interfaces
- Applet Use of spaces
- [case] a super easy-to-use tool -- a calculator for programmers
- Wechat applet (get location)
- MFS详解(七)——MFS客户端与web监控安装配置
- Uniapp secondary encapsulates uview components, and the parent component controls display and hiding
- Time complexity and space complexity
- Custom view - extensible collapsexpendview
猜你喜欢

AI realizes "Resurrection" of relatives | old photo repair | old photo coloring, recommended by free app

JS to realize bidirectional data binding

Echart line chart: multiple line charts show only one line at a time

Rk3399 hid gadget configuration

MFS详解(六)——MFS Chunk Server服务器安装与配置

SSM框架整合--->简单后台管理

Failed to extract manifest from apk: processexception:%1 is not a valid Win32 Application.

Echart line chart: different colors are displayed when the names of multiple line charts are the same
![[FAQs for novices on the road] understand program design step by step](/img/33/24ced00918bc7bd59f504cf1a73827.jpg)
[FAQs for novices on the road] understand program design step by step

本地文件秒搜工具 Everything
随机推荐
Time conversion'2015-04-20t11:12:00.000+0000 '
JVM Foundation
Dart class inherits and implements mixed operators
本地文件秒搜工具 Everything
How to view APK version number from apk
The web server failed to start Port 7001 was already in use
Kotlin basic string operation, numeric type conversion and standard library functions
1+1 > 2, share creators can help you achieve
Alibaba cloud OSS file download cannot be resumed at a breakpoint
楊輝三角形詳解
RN Metro packaging process and sentry code monitoring
电镀挂具RFID工序管理解决方案
自定义View
Wechat applet jumps to H5 page with parameters
MFS详解(六)——MFS Chunk Server服务器安装与配置
Differences among concurrent, parallel, serial, synchronous and asynchronous
[var const let differences]
万能播放器 PotPlayer 的下载与安装,直播流 m3u8 导入
Echart histogram: stacked histogram displays value
Echart line chart: when multiple lines have the same name, the legend is still displayed