battle programmers alliance
Would you like to react to this message? Create an account in a few clicks or log in to continue.

battle programmers allianceLog in

the LivinGrimoire Artificial General Intelligence software design pattern forum

descriptionkotling coroutines grimoire Emptykotling coroutines grimoire

more_horiz
android studio 4.1
coroutines are the same as threads, exept better (speed & stability wise)

in the gradle file add
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2"
in dependencies {}

this grimoire will start with 2 of the best code snippets for utilizing the
coroutine jutsu.
as a reminder, to run the main func, just paste it into a kt file, it
should have a run arrow next to the function.

mulan szechuan sauce to make codes faster and taste better:
launch jutsu. this codes runs multi functions in parallal

Code:

fun main()= runBlocking{

    var c1:Int=1;
    var test = ""
    var test2:String = "null"
    launch (Dispatchers.Default){ while (c1<5){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }
        test = async { tic("tek") }.await()
        test2 = "test ok"
    } }.join()
//.join can be omitted for extra speed
    println(test)
    println("test result : $test2")
    println("main thread end")
}
suspend fun tic(startNum: String):String{
    delay(1000)
    println(startNum)
    return  "test ok"
}


alter code :

Code:

fun main()= runBlocking{

    var c1:Int=1;
    var test = ""
    var test2:String = "null"
    launch (Dispatchers.Default){ while (c1<5){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }
        test = async { tic("tek") }.await()
        test2 = "test ok"
    } }.invokeOnCompletion { throwable -> println("done") }
//.join can be omitted for extra speed
    println(test)
    println("test result : $test2")
    println("main thread end")
}
suspend fun tic(startNum: String):String{
    delay(1000)
    println(startNum)
    return  "test ok"
}


###################################
kotlin android studio handler tick event alternative simpler stronger code :

Code:

fun main()= runBlocking{

    var c1:Int=1;
    launch (Dispatchers.Default){ while (c1<10){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }.await()
    } }
    println("main thread end")
}
suspend fun tic(startNum: String){
    delay(1000)
    println(startNum)
}


output :

main thread end
tick
tok
tick
tok
tok
tick
tok
tick
tick
tok
tok
tick
tick
tok
tick
tok
tok
tick

Process finished with exit code 0
##################################################

descriptionkotling coroutines grimoire EmptyRe: kotling coroutines grimoire

more_horiz

Code:

Java:
fun main(){
    println("main starts")
    routin(1,500)
    print("main ends")
}
fun routin(number: Int, delay: Long){
    println("routin $number starts work")
    Thread.sleep(delay)
    println("routin $number has finished")
}


click ▶ to run)
this runs and pauses on the main thread
####################################################

Code:

import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main(){
    exampleBlocking()
}

fun exampleBlocking() {
    println("one")
    //block thread and summon a coroutin :
    runBlocking { printlnDelayed("two") }
    println("three")
}

suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}

shorter write :

Code:

fun main(){
    exampleBlocking()
}

fun exampleBlocking() = runBlocking{
    println("one")
    //block thread and summon a coroutin :
    printlnDelayed("two")
    println("three")
}

suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}


#############################################

Code:

fun main(){
    exampleBlockingDispatcher()
}
fun exampleBlockingDispatcher(){
    runBlocking(Dispatchers.Default) {
        println("one - from thread ${Thread.currentThread().name}")
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    // Outside of runBlocking to show that it's running in the blocked main thread
    println("three - from thread ${Thread.currentThread().name}")
    // It still runs only after the runBlocking is fully executed.
}
suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}

a dispacher mostly switches the runblocking to a different thread
output :
one - from thread DefaultDispatcher-worker-1
two - from thread DefaultDispatcher-worker-1
three - from thread main

####################################################

descriptionkotling coroutines grimoire EmptyRe: kotling coroutines grimoire

more_horiz
global dispacher : this will run on a separate thread without blocking the
summoner thread :

Code:

fun main(){
    exampleLaunchGlobal()
}

fun exampleLaunchGlobalWaiting() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
 
    val job = GlobalScope.launch {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
 
    println("three - from thread ${Thread.currentThread().name}")
    job.join()
}
suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}


################################
coroutin on a launch scope :

fun exampleLaunchCoroutineScope() = runBlocking {
println("one - from thread ${Thread.currentThread().name}")
launch {
printlnDelayed("two - from thread ${Thread.currentThread().name}")
}
println("three - from thread ${Thread.currentThread().name}")
}

those will all run on the same thread
to change the thread of the dispacher :

Code:

fun exampleLaunchCoroutineScope() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
    launch(Dispatchers.Default) {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    println("three - from thread ${Thread.currentThread().name}")
}


also not to access the views like text views on android, this can oly be done via the
main thread or Dispacher.main

using your own custom dispacher :


Code:

fun exampleLaunchCoroutineScope() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
    val customDispatcher = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
    launch(customDispatcher) {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    println("three - from thread ${Thread.currentThread().name}")
}


####################################
async with value get set:

Code:

suspend fun calculateHardThings(startNum: Int): Int {
    delay(1000)
    return startNum * 10
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()

    val deferred1 = async { calculateHardThings(10) }
    val deferred2 = async { calculateHardThings(20) }
    val deferred3 = async { calculateHardThings(30) }

    val sum = deferred1.await() + deferred2.await() + deferred3.await()
    println("async/await result = $sum")

    val endTime = System.currentTimeMillis()
    println("Time taken: ${endTime - startTime}")
}


you can also use await like this :
val deferred1 = async { calculateHardThings(10) }.await()
#############################################################
kotlin coroutins async timer

Code:

suspend fun calculateHardThings(startNum: String){
    delay(1000)
    println(startNum)
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()
    var c1:Int=1;
    while (c1<10){
        c1++;
        val deferred1 = async { calculateHardThings("tick") }
        val deferred2 = async { calculateHardThings("tok") }.await()
    }

    println("end")
}


###############################################################
if you want to run things async but not block the thread and with context:
which is the same as calling await after each async.
this is best used for heavy calculations so as to not burden the main or UI thread

Code:

suspend fun calculateHardThings(startNum: Int): Int {
    delay(1000)
    return startNum * 10
}
fun exampleWithContext() = runBlocking {
    val startTime = System.currentTimeMillis()

    val result1 = withContext(Dispatchers.Default) { calculateHardThings(10) }
    val result2 = withContext(Dispatchers.Default) { calculateHardThings(20) }
    val result3 = withContext(Dispatchers.Default) { calculateHardThings(30) }

    val sum = result1 + result2 + result3
    println("async/await result = $sum")

    val endTime = System.currentTimeMillis()
    println("Time taken: ${endTime - startTime}")
}


###################################
timer on BG thread :

Code:

fun main(){
    exampleAsyncAwait()
    println("main thread end")
}
suspend fun calculateHardThings(startNum: String){
    delay(1000)
    println(startNum)
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()
    var c1:Int=1;
    launch { while (c1<10){
        c1++;
        val deferred1 = async { calculateHardThings("tick") }
        val deferred2 = async { calculateHardThings("tok") }.await()
    } }

    println("end")//main code thread, does not wait for the timer which is in the BackGround
}

descriptionkotling coroutines grimoire EmptyRe: kotling coroutines grimoire

more_horiz
#################

Code:

fun main()= runBlocking{

    repeat(1_000){
        launch { delay(1000)
        print("creamed corn")}
    }
}


unlike threads you can summon a million coroutins and it runs very fast

Code:

fun main()= runBlocking<Unit>{
//official write style
    repeat(1_000){
        launch { delay(1000)
        print("creamed corn")}
    }
}

#####################################

Code:

fun main()= runBlocking<Unit>{
//official write style
        val job = launch { delay(1000)
        print("creamed corn")}
    job.join()//run once
}


Code:

fun main()= runBlocking<Unit>{
//official write style
        val job = launch(start = CoroutineStart.LAZY) { delay(1000)
        print("creamed corn")}
    delay(200)
    job.start()//start launch with delay
}


####################################################

timeout job cancelation :

Code:

fun main()= runBlocking<Unit>{
//official write style
        val job = GlobalScope.launch { print("creamed corn")
        withTimeout(3000){
            //if this code doesn't finish in timeout time it is canceled
            delay(500)
            print("creamed corn")
            delay(3000)
            print("finished")// doesn't print
        }
        }
}


manual launch job cancelation :

Code:

fun main()= runBlocking<Unit>{
//official write style
        val job = launch {
        withTimeout(3000){
            println("test")    ;this.cancel();      delay(10)

            println("you can not see me in the output window")
        }
        }
}


##############################
measure function run time

Code:

@ExperimentalTime
fun main()= runBlocking<Unit>{
//official write style

    launch {
        val duration = measureTime { calculateHardThings(1000) }
        println(duration)
    }
}


###############################
setting coroutine context to default so as to not jam the UI :

Code:

@ExperimentalTime
fun main()= runBlocking<Unit>{
//official write style

    launch (context = Dispatchers.Default){
        val duration = measureTime { calculateHardThings(1000) }
        println(duration)
    }
}


###############################3
access cancellation event for coroutine :

Code:

val scope= CoroutineScope(Dispatchers.Default)
fun main ()= runBlocking {
    val job = scope.launch {
        delay(100)
        println("coroutine completed")
    }
    job.invokeOnCompletion { throwable ->  if(throwable is CancellationException){println("the coroutine has been cancelled")} }
    delay(50)
    onDestroy()
}

fun onDestroy(){
    println("lifecycle end")
    scope.cancel()
}


#############################

would you like to know more ?
https://www.geeksforgeeks.org/scopes-in-kotlin-coroutines/

####################################
cancelling a coroutine with a default dispacher :

Code:

fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        repeat(10){index ->
            ensureActive()
            println("operation: $index")
            Thread.sleep(100)
        }
    }
    delay(250)
    println("cancelling coroutin")
    job.cancel()
}


ensuring no cancelling on cancelled coroutins clean up code block :

Code:

fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        repeat(10){index ->
            if(isActive){println("operation: $index");Thread.sleep(100)}
            else{
                withContext(NonCancellable){
                    delay(100)
                    println("clean up")
                    throw CancellationException()
                }}
        }
    }
    delay(250)
    println("cancelling coroutin")
    job.cancel()
}


:rain:

descriptionkotling coroutines grimoire EmptyRe: kotling coroutines grimoire

more_horiz
volatile var :

Code:

import android.arch.lifecycle.ViewModel
import android.support.annotation.RestrictTo
import kotlinx.coroutines.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
@Volatile var fudge = "fudge" //wherever this var is accessed from it will retrieve or save the latest value
fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        var finished :Boolean = false;
        repeat(10000){index ->
            if(!finished){
            delay(10)
            if (fudge.equals(" morphed")){println(index);finished=true}
        }}
    }
    delay(200)
    fudge = " morphed"
    print(fudge)
}
privacy_tip Permissions in this forum:
You cannot reply to topics in this forum
power_settings_newLogin to reply