Kotlin coroutine (1) basic understanding

tags: Kotlin


I. Coroutine kotlin thread switching framework

Typical application:

  • Start a coroutine and specify the CoroutineContex coroutine context (including running threads and thread pools, etc.)
  • It contains other coroutines (less such operations), suspend functions (more), multi-threaded operation codes (more), etc.;
  • When a suspended function is encountered, it will enter the function, switch the thread to the thread specified by the suspended function, and after the execution is complete, switch back to the original thread and continue execution.

II. suspend fun

Suspending a function will suspend the coroutine; suspending is not blocking.
The most direct usage of is to enter a suspended function in the main thread to execute it;

If the suspend function is assigned a thread by a coroutine, the thread will be switched to run;
Regardless of whether the thread is cut or not, the execution continues after the suspend function is executed.
However, if the thread is not specified by a sub-coroutine, then it will not wait until the thread is completely executed. (If usedThreadThreadPoolExecutorTo start the thread)

decompile will see that the suspend function is packaged asContinuation Object throughContinuation#resumeWith(result:Result<T>) Get results,result.isFailure/isSuccess Suspended function failed/successful; after the result of the suspended function is obtained externally, it executes backward.

suspend itself cannot allow functions to be suspended. Used in conjunction with the coroutine, or in other suspend functions to perform suspend operations.
The suspend function requires to be called by a coroutine or another suspend function. The ultimate goal is to be run by the coroutine.

suspend fun m() {
	//withContext is a suspend function
	withContext(Dispatchers.IO) {
		...
	}
}

Once the suspend function suspends the coroutine (not necessarily switching threads), the coroutine code will be suspended and not run down until the suspend function is executed.

withContext(), a suspend function provided by Kotlin:

public suspend fun <T> withContext(
		context: kotlin.coroutines.CoroutineContext, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	) : T {   }

III. Create a coroutine

a. CoroutineScope

Create CoroutineScope:

  • runBlocking() Blocking. It will wait until all internal sub-coroutines and suspended functions are executed. Internally createdBlockingCoroutine Blocking coroutine object
  • MainScope() There is no specific implementation in the standard library (writing a console demo will report an error). There are in Android. The scope of the coroutine of the main thread.
  • GlobalScope It is an object class. Global scope. It will not be cancelled with the cancellation of the parent's non-global scope.
  • Custom implementation
class MyCoroutineScope(
		override val coroutineContext: CoroutineContext
	) : CoroutineScope

CoroutineScope The extension function:

  • launch() Non-blocking. By default, it depends on CoroutineContext of CoroutineScope. Return to Job. Internally, a StandaloneCoroutine object is created (it implements Job, Continuation, CoroutineScope).
  • async() Non-blocking. A new CoroutineContext will be created. Create DeferredCoroutine objects internally (they Deferred, Job, Continuation, CoroutineScope DefaultDispatcher)

b. launch()

public fun kotlinx.coroutines.CoroutineScope.launch(
		context: kotlin.coroutines.CoroutineContext, 
		start: kotlinx.coroutines.CoroutineStart, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> kotlin.Unit
	) : kotlinx.coroutines.Job {  }

About parameters:
context : CoroutineContext coroutine context
start : CoroutineStart coroutine start mode
block : A pending, CoroutineScope, anonymous extension function. Internal functioncoroutineScope(block){} CreateCoroutineScope Coroutine scope object.
Note: CoroutineScope.() is declared like an extension function, but there is no function name. However, through testing, it is found that the call of the block actually needs to pass in a CoroutineScope object, so the CoroutineScope object is created when the block function is called.
wrote an example,

fun test(v: Int, block: Int.()  -> Double) {
   println(block(v * 2)) //println 2048.0
}
fun calc(a: Int): Double {
   return (a shl 10) * 1.0 //2<<10 = 2048
}
test(1) {
   calc(this)
   //18.5
}

Call test(), pass in an int parameter, and a function; that is, {calc(this)} as a whole is the block parameter in test;
In the test() implementation, print the return value of block(); block needs an Int parameter, here v is multiplied by 2;
block <==> {calc(this)}, at this time this = 2, the calc function will get 2048.0 after running;
Finally, the return value of block 2048.0 is printedln()
 
If the "18.5" statement in the comment is turned on, it is the return value of block(). Kotlin syntax, where the result of the last line of code is regarded as the return value.

c. async()

public fun <T> kotlinx.coroutines.CoroutineScope.async(
		context: kotlin.coroutines.CoroutineContext, 
		start: kotlinx.coroutines.CoroutineStart, 
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	): kotlinx.coroutines.Deferred<T> { }

d. runBlocking()

public fun <T> runBlocking(
		context: kotlin.coroutines.CoroutineContext,  
		block: suspend kotlinx.coroutines.CoroutineScope.() -> T
	): T {  }

When these functions are declared, the context and start are all given default values.
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,

e. Coroutine start mode CoroutineStart

public enum class CoroutineStart {
    DEFAULT, 						//The default mode, execute the coroutine body immediately
    LAZY,							//Run only when needed
    @ExperimentalCoroutinesApi		//Experimental coroutine api
    ATOMIC,							//
    @ExperimentalCoroutinesApi
    UNDISPATCHED;					//
}

f. Job

Main member functions:

  • jon() Wait for the coroutine to finish executing. (Similar to Thread#join())
  • cancel()Cancel the coroutine. All suspended functions in the coroutine are cancelable. They check the cancellation of the coroutine and throw a CancellationException on cancellation.
  • cancelAndJoin() The internal is to cancel() first and then join(). Wait for the cancel operation to complete

g. Deferred

It is a sub-interface of Job. There is mainly oneawait()
await() Is a suspend function, it has a return type <T>.
When calls it, the coroutine will be suspended, and a result T will be obtained after execution.

h. Dispatchers scheduler

Implemented from CoroutineContext.

public actual object Dispatchers {
	public actual val Default: CoroutineDispatcher = createDefaultDispatcher()
	public actual val Main: MainCoroutineDispatcher get() = 
			MainDispatcherLoader.dispatcher
	public actual val Unconfined: CoroutineDispatcher = 
			kotlinx.coroutines.Unconfined
	public val IO: CoroutineDispatcher = DefaultScheduler.IO
}

Main can be used in Android, that is, the UI thread; it cannot be used in the console and is not implemented.
A dispatcher thread in the IO internal thread pool; performs disk or network I/O intensive;
Default a dispatcher thread in the internal thread pool, which executes cpu-intensive;
Unconfined

i. Other suspend functions

  • delay() How many milliseconds the coroutine hangs. (Similar to Thread.sleep())
  • yield() If possible, provide the thread (or thread pool) of the current coroutine Dispatchers to other coroutines to run. (Similar to Thread.yield() ). In the following example, the output will be interleaved:
// Same as Main, Default, and Unconfined, they will be in the same thread when yield switches the running coroutine.
// IO will create a new thread. Inside Default is a thread pool.
runBlocking {
    launch(Dispatchers.Unconfined, CoroutineStart.LAZY) {
        for (i in 0..3) {
            println("aaaa ${Thread.currentThread().name}")
            yield()
        }
    }
    launch(Dispatchers.Unconfined, CoroutineStart.LAZY) {
        for (i in 0..3) {
            println("bbbb  ${Thread.currentThread().name}")
            yield()
        }
    }
}

IV. Use process

  • First create a coroutine scope (at the same time, a coroutine will be created internally)
  • In the scope of the coroutine, in addition to ordinary code, it can contain other coroutines and suspend functions (of course, there can also be sub coroutines in the suspend function)
  • You can specify CoroutineContext, Dispatchers, CoroutineStart
  • Do you need to perform join and cancel operations on the coroutine, or do you want to await the result; to choose between lanuch() or async();
    Deferred is a subclass of Job and also has join and cancel operations.
  • withContext is a suspend function. Use it, that is, do not care about the join, cancel, await operations of the coroutine

Intelligent Recommendation

Probe into Kotlin Coroutine (1)

Probe into Kotlin Coroutine (1) 2017, Google announcedKotlin Become an official development language of Android and adds support for COROUTINE (equation, simply as a lightweight thread) at version 1.1...

Deep understanding of Kotlin coroutine (2)

Last week we talked about Kotlin Coroutine's basic API and gave some simple packages. I don’t want to give it too much. Just in the 1.1 Beta 2 released a few days ago, all the coroutine API pack...

In -depth understanding of the Koltin coroutine (1): Why do you learn the Kotlin coroutine?

Series e -book:Portal Why learn Kotlin coroutines? We already have a very complete type of JVM library, such as RXJAVA and Reactor. In addition, Java itself supports multi -threaded threads, and most ...

Kotlin coroutine bytecode parsing -1

Background Kotlinx.coroutines is a feature-rich coroutine library developed by JetBrains. It contains many of the primitives that enable advanced coroutines covered in this guide, including launch, as...

Kotlin Coroutine (1): Foundation and In-depth

First, access Second, the way of use Commonly used ways: CoroutineScope.launch() CoroutineScope.async() Third, about the exemplary example JOB is used to handle the level. For each created sweeper (vi...

More Recommendation

Channel channel of the coroutine in Kotlin (1)

Channel channel of the coroutine in Kotlin (1) Channel-channel Channel capacity Iterate Channel Produce and Actor Channel's closure BroadcastChannel Channel-channel Channel is actually a secure queue,...

Understanding of the coroutine (1)

Learn and organize the following content through Liao Xuefeng's Python3 Learning Tutorial. Original address: concept Coroutine, English name: Coroutine The coroutine is a single-threaded execution mod...

In-depth understanding Kotlin Extension (1) - Basic Concept

In-depth understanding Kotlin Extension (1) Basic concept of the sweeper Classification of the extension Classification by calling Classified by scheduling Extension Creation of the extension Triding ...

Kotlin coroutine and RXJAVA analysis and understanding (2)

Combined with Retrofit Create service, the return type is custom response Create a repository, here is a 2 -second delay for testing Create ViewModel Initialize the coroutine, Coroutinescope follows A...

Coroutine of kotlin introductory training-basic concepts

This article is included inKotlin Introductory Submarine Training Series, Welcome to learn and communicate. Creation is not easy, if you reprint, please also note. Write in front If you are ambitious,...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top