Skip to content

Latest commit

ย 

History

History
1095 lines (861 loc) ยท 25.3 KB

README.md

File metadata and controls

1095 lines (861 loc) ยท 25.3 KB

Kotlin

์ฝ”ํ‹€๋ฆฐ

#๊ธฐ๋ณธ์€ ์ž๋ฐ”
fun main(){
    print("hello world") #mainํ•จ์ˆ˜๋Š” fun main(){}, ์„ธ๋ฏธ์ฝœ๋ก ์€ ์žˆ์–ด๋„ ๋˜๊ณ  ์—†์–ด๋„ ๋˜๊ณ 
    #prinln ๋„ ์กด์žฌ
}

๊ธฐ๋ณธ ๋ณ€์ˆ˜๋Š” var (๋ณ€์ˆ˜๋ช…) = (๊ฐ’)

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€์ˆ˜ํ˜•ํƒœ๋Š” ์•Œ์•„์„œ ์ถ”๋ฆฌ

๋ณ€์ˆ˜๋ช… ์ •ํ•  ์‹œ->var (๋ณ€์ˆ˜๋ช…) : (Int, String, Double.....) = (๊ฐ’)

์ƒ์ˆ˜๋Š”->val (๋ณ€์ˆ˜๋ช…) = (๊ฐ’)

์ƒ์ˆ˜๋Š” ๊ฐ’ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€

์ „์—ญ๋ณ€์ˆ˜๋Š” ๋ฉ”์ธ ํ•จ์ˆ˜ ๋ฐ–์—

๋ณ€์ˆ˜ or์ƒ์ˆ˜ ์•ž์— const ๋ถ™์ผ ์‹œ ๋ฉ”์ธํ•จ์ˆ˜๋ณด๋‹ค ๋จผ์ € ์ปดํŒŒ์ผ

ํ˜•๋ณ€ํ™˜

var i = 10
var l = 20L
var name = "10"
i = name.toInt() #(๋ณ€์ˆ˜๋ช…).to+(์›ํ•˜๋Š” ํ˜•)() ํ˜•ํƒœ๋กœ ์ž…๋ ฅ

๋ฒ ์ด์Šค๊ฐ€java

ใ„ดuppercase,lowercase์‚ฌ์šฉ ๊ฐ€๋Šฅ

ใ„ด๋ฐฐ์—ด๋„ ๋ณ€์ˆ˜๋ช…[] ์‚ฌ์šฉ ๊ฐ€๋Šฅ

ใ„ดprintํ•  ๋•Œ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋ฉด + ๋Œ€์‹  $(๋ณ€์ˆ˜๋ช…) ๋˜๋Š” ${(๋ณ€์ˆ˜๋ช…)}

ใ„ดKotlin.math.max(),min() ์‚ฌ์šฉ ๊ฐ€๋Šฅ

random ์‚ฌ์šฉํ• ๋•Œ๋Š”

val randeomNumber = Randem.nextInt(0,100) #0~99๊นŒ์ง€

์ฒ˜๋Ÿผ ์‚ฌ์šฉ

ํ‚ค๋ณด๋“œ ์ž…๋ ฅ

val reader = Scanner(System.'in')
reader.nextInt() #์ˆซ์ž์ž…๋ ฅ
reader.next() #๋ฌธ์ž์ž…๋ ฅ

if๋ฌธ

java์™€ ๋™์ผ

when๋ฌธ

var i = 5
when {
    i>10 -> {
        print("10๋ณด๋‹ค ํฌ๋‹ค")
    }
    i > 5 ->{
        print("5๋ณด๋‹ค ํฌ๋‹ค")
    }
}

๋ณ€์ˆ˜์— if or when ์ž…๋ ฅ ๊ฐ€๋Šฅ

3ํ•ญ์—ฐ์‚ฐ์ž

var i = 5
var result = if (i>10) true else false

๋ฐ˜๋ณต๋ฌธ

val items = listOf(1,2,3,4,5)
for (item in items){
    print(item)
}
val items = listOf(1,2,3,4,5)
for (i in 0..(items.size -1)){
    print(item)
}

forEach

items.forEach {item ->
    print(item)
}

๋ฆฌ์ŠคํŠธ

๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•œ list๋งŒ๋“ค๋•Œ๋Š”

val items = mutableListOf(1,2,3,4,5)
items.add(6)
items.remove(3)

array

val items = arrayOf(1,2,3)
items[0] = 10

try catch

try{

} catch (e.message){

}

null

var name: String? = null #String? ๋Š” String์™€ ๋‹ค๋ฅด๋‹ค

null์ด ์•„๋‹ ๋•Œ ์‹คํ–‰ํ•˜๋ ค๋ฉด

name?.let{
    name2 = name
}

ํ•จ์ˆ˜

fun sum(a:Int, b:Int) : Int{
    return a+b
}

๋˜๋Š”

fun sum(a:Int, b:Int) = a+b

class

fun name(){
    val jhon = Person("John", 20)
    print(jhon.name, jhon.age)
}
class Person(val name: String, var age : Int,)

getter setter

override๋ฅผ ํ†ตํ•ด ์„ค์ • or class ์•ž์— data ๋ถ™์ด๊ธฐ

data class Person()

init

class๊ฐ€ ์‹คํ–‰๋ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋ ค๋ฉด init ์‚ฌ์šฉ

class Person(){
    init{
        print("1")
    }
}

init ๋ถ€๋ถ„์— private set ์ž‘์„ฑ ์‹œ ์™ธ๋ถ€์—์„œ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€

field

class Person(){
    var hobby = "์ถ•๊ตฌ"
    private set
    get() = "์ทจ๋ฏธ": $field #์—ฌ๊ธฐ๋Š” ๋ณ€์ˆ˜๋ช…์ด ์•„๋‹Œ field ์‚ฌ์šฉ
    init{
        print("1")
    }
}

์ƒ์†

fun main(){
}
class dog{
    fun move(){
        //
    }
}
class cat{
    fun move(){
        //
    }
}

์„ ๋ฐ”๊พธ๋ฉด

fun main(){
}
abstract ckass Animal{
    open fun move(){ #์ฝ”ํ‹€๋ฆฐ์€ ์ƒ์†๋ฐ›์•„๋„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด open ํ•„์š”
        print("์ด๋™")
    }
}
class dog : Animal(){
    override fun move(){
        println("๊ป‘์ถฉ")
    }
}
class cat : Animal(){
    override fun move(){
        println("์‚ด๊ธˆ")
    }
}

interface

fun main(){
}
interface Drawable{
    fun draw()
}
abstract ckass Animal{
    open fun move(){ #์ฝ”ํ‹€๋ฆฐ์€ ์ƒ์†๋ฐ›์•„๋„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด open ํ•„์š”
        print("์ด๋™")
    }
}
class dog : Animal(), Drawable{ #์†Œ๊ด„ํ˜ธ ์—†์Œ
    override fun move(){
        println("๊ป‘์ถฉ")
    }
}
class cat : Animal(){
    override fun move(){
        println("์‚ด๊ธˆ")
    }
}

์ดํ•ด ๋” ํ•„์š”

type check

fun main(){
    val dog : Animal = DOG()
    val cat = Cat()

    if(dog is Dog){
        println("๋ฉ๋ฉ์ด")
    }
}
interface Drawable{
    fun draw()
}
abstract ckass Animal{
    open fun move(){
        print("์ด๋™")
    }
}
class dog : Animal(), Drawable{
    override fun move(){
        println("๊ป‘์ถฉ")
    }
}
class cat : Animal(){
    override fun move(){
        println("์‚ด๊ธˆ")
    }
}

์ œ๋„ค๋ฆญ

fun main(){
    val box = Box(10)
    val box2 = Box("dfdfdf")

    print(box.value)
}
class box<T>(var value: T){

}

์ดํ•ด ๋” ํ•„์š”

์ฝœ๋ฐฑ

fun main(){
    myFunc(10){ #๋žŒ๋‹ค์‹?
        println("ํ•จ์ˆ˜ ํ˜ธ์ถœ")
    }
}
fun myFunc(a:Int,callBack : () -> Unit){
    println("ํ•จ์ˆ˜ ์‹œ์ž‘")
    callBack()
    println("ํ•จ์ˆ˜ ๋")
}

suspend

์ด๋ž˜์ €๋ž˜ ์ดํ•ด ๋” ํ•„์š”?

์ฝ”๋ฃจํ‹ด

์ฝ”๋ฃจํ‹ด(Coroutine)์€ ์ผ๋ฐ˜ ๋ฃจํ‹ด๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ค‘๋‹จ๊ณผ ์žฌ๊ฐœ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ค‘๋‹จํ•œ ๊ณณ์—์„œ ์žฌ๊ฐœ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ฝ”๋ฃจํ‹ด์ด ์ˆœ์ฐจ์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

suspend์— ๋Œ€ํ•œ ์ดํ•ด ๋ฐ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๊ณต๋ถ€๊ฐ€ ๋” ํ•„์š”ํ•œ ๋“ฏ...

๋ฌผ๋ก  ํ›„๋ฐ˜์— ๊ฐˆ์ˆ˜๋ก ์–ด๋ ค์›Œ์ง€์ง€๋งŒ ์‹œ์ž‘ํ•˜๊ธฐ์—๋Š” ์–ด๋ ต์ง€ ์•Š๋‹ค

import kotlinx.coroutines.*
fun main(){
    GlobalScope.launch{this: CoroutinesScope //launch:์ฝ”๋ฃจํ‹ด ๋นŒ๋“œ, GlobalScope:๋ฉ”์ธ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™๋œ ํ›„ ์‹คํ–‰.
    delay(timeMillis: 1000L)
    println("World!")
    }
    println("Hello,")
    Thread.sleep(2000L)
}

ใ„ดํ•œ๋ฒˆWorld!๋ฅผ ์‹คํ–‰ ํ›„ ๊ณ„์† ์‹คํ–‰ํ•œ๋‹ค๋Š”๋ฐ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋ ์–ด์„œ World!๊ฐ€ 2๋ฒˆ ์ด์ƒ ์ธจ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•จ...์–ด์จฐ์„œ..?

ใ„ด๋‹ค์‹œ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๋ฉ”์ธ ์ฝ”๋“œ์™€ ์ฝ”๋ฃจํ‹ด์„ ๋™์‹œ์— ์‹คํ–‰์‹œํ‚ค๋Š”๋ฐ ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์กฐ๊ฑด์€ ๋ฉ”์ธ ํ”„๋กœ๊ทธ๋žญ ์ข…๋ฃŒ์ด๋‹ˆ ๊ทธ๋Ÿฐ๋“ฏ?

import kotlinx.coroutines.*
fun main(){
    GlobalScope.launch{this: CoroutinesScope
        delay(timeMillis: 1000L)
        println("World!")
    }
    println("Hello,")
    runBlocking{this:CoruotineScope //์ฝ”๋ฃจํ‹ด ์‹คํ–‰์šฉ runBlocking
        delay(timeMillis: 2000L)
    }
}
import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        GlobalScope.launch{this: CoroutinesScope //launch:์ฝ”๋ฃจํ‹ด ๋นŒ๋“œ, GlobalScope:๋ฉ”์ธ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™๋œ ํ›„ ์‹คํ–‰.
        delay(timeMillis: 1000L)
        println("World!")
        }
        println("Hello,")
        delay(timeMillis: 2000L)
    }

import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        val job = GlobalScope.launch{this: CoroutinesScope
            delay(timeMillis: 3000L)
            println("World!")
        }
        println("Hello,")
        job.join() //์•„๋งˆ ํ•จ์ˆ˜ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฑฐ๋กœ ๋ณด์ž„
    }

Structured concurrency

import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        this.launch{this: CoroutinesScope //launch:์ฝ”๋ฃจํ‹ด ๋นŒ๋“œ, GlobalScope:๋ฉ”์ธ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™๋œ ํ›„ ์‹คํ–‰.
            delay(timeMillis: 3000L)
            println("World!")
        }

        launch{this: CoroutinesScope //launch:์ฝ”๋ฃจํ‹ด ๋นŒ๋“œ, GlobalScope:๋ฉ”์ธ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™๋œ ํ›„ ์‹คํ–‰.
            delay(timeMillis: 3000L)
            println("World!")
        }
        println("Hello,")
    }

๊ฒฐ๋ก ์ ์œผ๋กœ ์‹คํ–‰๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ๊ฒƒ์ด ์ŠคํŠธ๋Ÿญ์ณ๋“œ ์ปจํฌ๋Ÿฌ์‹œ์ด๊ณ  ์ƒ๋‹นํžˆ ์ž์ฃผ ๋‚˜์˜จ๋‹ค.

import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        launch{this: CoroutinesScope
            myWorld()
        }
        println("Hello,")
}
suspend fun myWorld(){
    delay(timeMillis: 1000L)
    println("world!")
}

ใ„ด์„œ์ŠคํŽœ๋“œ ํ‰์…˜(์˜ˆ:delay)๋Š” ์„œ์ŠคํŽœ๋“œ ๋ฐ ์ฝ”๋ฃจํ‹ด์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค

fun main() = runBlocking{
    repeat(100_000){
        launch{
            delay(1000L)
            print(".")
        }
    }
}

ใ„ด์ฝ”๋ฃจํ‹ด์ด ๊ฐ€๋ณ๋‹ค ์ฆ๋ช…์šฉ ์ฝ”๋“œ

import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        GlobalScope.launch {this: CoroutineScope
        repeat(times:1000) {i->
        println("I'm sleeping $i ...")
    delay(timeMillis: 500L)
        }
    }
    delay(timeMillis: 1300L)
}

ใ„ด๋ฉ”์ธํ”„๋กœ์„ธ์Šค๊ฐ€ ๋๋‚  ์‹œ ์ฝ”๋ฃจํ‹ด๋„ ๋๋‚œ๋‹ค๋Š” ์ฝ”๋“œ

import kotlinx.coroutines.*
fun main() =
    runBlocking{this: CoroutineScope
        launch {this: CoroutineScope
            repeat(times:5) {i->
            println("Coroutine A,  $i ...")
            delay(timeMillis:10L)
            }
        }
        launch {this: CoroutineScope
            repeat(times:5) {i->
            println("Coroutine B,  $i ...")
            delay(timeMillis:10L)
            }
        }
    println("Coroutine Outer")
}

ใ„ด์ฝ”๋ฃจํ‹ด์˜ ์ค‘๋‹จ ๋ฐ ์žฌ๊ฐœ์˜ ์˜ˆ์‹œ ์ฝ”๋“œ

๋ฉ”์ธ ์ฝ”๋“œ์™€ ์ฝ”๋ฃจํ‹ด์€ ๋™์‹œ์— ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฝ”๋ฃจํ‹ด๋ผ๋ฆฌ๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ž‘ํ•˜์—ฌ์„œ

๋‚ด๋ถ€ ์ž‘์—…์€ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

๋ณ‘๋ ฌ๋กœ ๋™์ž‘ํ•˜๋ ค๋ฉด ๋™์‹œ์„ฑ์„ ์ œ์–ดํ•ด์•ผ ํ•œ๋‹ค.(await,async,delay๋“ฑ ์‚ฌ์šฉ)

์ฝ”๋ฃจํ‹ด 3๊ฐ•

import kotlinx.coroutines.*

fun main() = runBlocking { this: CoroitineScope
    val job = launch { this: CoroutinesScope #์บ”์Šฌ ๊ฐ€๋Šฅ ๊ฐœ์ฒด
        repeat(time:1000) {i ->
            prinln(msg:"job: I'm sleeping $i ...")
        delay(timeMillis: 500L)
        }
    }
    delay(timeMillis: 1300L)
    println(msg: "main: I'm tried of waiting!")
    job.cancle()
    job.join()
    println(msg: "main: Now I can quit")
}

์‹คํ–‰๊ณผ ๋™์‹œ์— job์ด ์‹คํ–‰->1.3์ดˆ ํ›„์— cancle์ด ์‹คํ–‰๋˜๊ณ  ์ •์ง€ํ•จ->(๊ทธ๋Ÿผ join์€ ์–ด์งธ์„œ ์กด์žฌํ•˜๋Š”๊ฐ€?)????

import kotlinx.coroutines.*

fun main() = runBlocking {
    val startTime = currentTimeMillis()
    val job = launch(Dispatchers.Default) {
        var nextPrintTime = startTime
        var i = 0
        while (i < 5) { // computation loop, just wastes CPU
            // print a message twice a second
            //yield()
            if (currentTimeMillis() >= nextPrintTime) {
                println("job: I'm sleeping ${i++} ...")
                nextPrintTime += 500L
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
}

cancleandjoin์ด ์ž˜ ์ž‘๋™๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” delay๊ฐ™์€ ์„œ์ŠคํŽœ๋“œ ํŽ‘์…˜์ด ์—†์–ด์„œ

yield()๊ฐ€ ์žˆ์œผ๋ฉด delay์—†์ด๋„ ๊ฐ€๋Šฅ

import kotlinx.coroutines.*

fun main() = runBlocking {
    val startTime = currentTimeMillis()
    val job = launch(Dispatchers.Default) {
        var nextPrintTime = startTime
        var i = 0
        while (isActive) { // cancellable computation loop
            // print a message twice a second
            if (currentTimeMillis() >= nextPrintTime) {
                println("job: I'm sleeping ${i++} ...")
                nextPrintTime += 500L
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
}

isActive๋Š” ์ฝ”๋ฃจํ‹ด์ด ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ํŒ๋ณ„ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ cancle๋กœ ์ธํ•ด ๋ถˆํ—ˆ๋˜์–ด์„œ ์ฝ”๋“œ ์ •์ง€

import kotlinx.coroutines.*

fun main() = 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 a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
}

cancle์ด ์ต์…’์…˜์„ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ๊ทธ๊ฒƒ์œผ๋กœ ์ธํ•ด try๊ฐ€ ์•„๋‹Œ finally๊ฐ€ ์‹คํ–‰๋œ๋‹ค

import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(1000) { i ->
                println("job: I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
            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")
            }
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancelAndJoin() // cancels the job and waits for its completion
    println("main: Now I can quit.")
}

rareํ•œ ์ผ€์ด์Šค, ์ •์ง€๋œ ์ฝ”๋ฃจํ‹ด ์•ˆ์—์„œ ์ฝ”๋ฃจํ‹ด์ด ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ

import kotlinx.coroutines.*

fun main() = runBlocking {
    withTimeout(1300L) {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
}

0.5์ดˆ์”ฉ 1000๋ฒˆ ๋ฐ•๋ณตํ•˜๋Š” ์ฝ”๋“œ์ธ๋ฐ withTimeout์„ ํ†ตํ•ด ์ •์ง€์‹œํ‚จ๋‹ค.(ํ—ˆ๋‚˜ ๋ฉ”์ธ ์ฝ”๋“œ์—ฌ์„œ ๊ทธ๋Ÿฐ์ง€ ์ต์…’์…˜์ด ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.)

import kotlinx.coroutines.*

fun main() = runBlocking {
    val result = withTimeoutOrNull(1300L) {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
        "Done" // will get cancelled before it produces this result
    }
    println("Result is $result")
}

์ด๋ฒˆ์—๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚  ์‹œ null๊ฐ’์œผ๋กœ ๋ฐ”๋€Œ๊ณ  ๊ฐ’์ด "Done"์œผ๋กœ ๋ฐ”๋€Œ๋Š” ์ฝ”๋“œ์ด๋‹ค.

if๋ฌธ๋„ ์•„๋‹Œ๋ฐ ์‚ฌ์‹ค ์™œ "Done"๊ฐ’์ด ๋‚˜์˜ค๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค.

ใ„ด์ฐพ์•„๋ณด๋‹ˆ whitTimeOrNull์ด ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‚˜์˜จ ํ‘œํ˜„์‹์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•ด์„œ "Done"์ด ์ถœ๋ ฅ๋˜๋Š” ๋“ฏ ํ•˜๋‹ค.(if๋ฌธ ๋น„์ˆซํ•œ ๊ฒƒ ๊ฐ™๊ธฐ๋„..?)

์ฝ”๋ฃจํ‹ด 4๊ฐ•

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = doSomethingUsefulOne()
        val two = doSomethingUsefulTwo()
        println("The answer is ${one + two}")
    }
    println("Completed in $time ms")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

์ˆœ์ฐจ์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ์ฝ”๋“œ

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async { doSomethingUsefulOne() }
        val two = async { doSomethingUsefulTwo() }
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

์ˆœ์ฐจ์ ์œผ๋กœ ->๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰(์‹คํ–‰์‹œ๊ฐ„ ์ค„์ด๊ธฐ),async์‹คํ–‰์‹œ ์ฝ”๋“œ ์‹คํ–‰ ์‹œ์ž‘๋งŒ ํ•˜๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ์ค„๋กœ ๋„˜์–ด๊ฐ,await->async ์ž‘๋™๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
        val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
        // some computation
        one.start() // start the first one
        two.start() // start the second one
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

๋ผ์ธ์˜ start์— LAZY๋ฅผ ๊ฑธ์—ˆ์„ ๋•Œ start๋ฅผ ๊ฑธ์–ด์•ผ ์ž‘๋™ ์‹œ์ž‘๋˜๋„๋ก ์ฝ”๋”ฉ,๋งŒ์•ฝ start๋ฅผ ํ•˜์ง€ ์•Š์„ ์‹œ await๋ฅผ ๋งŒ๋‚˜์•ผ ์‹คํ–‰์ด ๋˜์„œ 2์ดˆ๊ฐ€ ๊ฑธ๋ฆผ

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
        val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
        // some computation
        one.start() // start the first one
        two.start() // start the second one
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

์œ„ ์˜ˆ์‹œ๋Š” ํ•˜์ง€ ๋ง๋ผ๋Š” ์˜ˆ์‹œ์ด๋‹ค. ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์‹œ ํฐ์ผ์ด ๋ฒŒ์–ด์ง(์™ธ๋ถ€ํ•จ์ˆ˜์—ฌ์„œ ์ต์…’์…˜์ด ๋ฐœ์ƒํ•˜์—ฌ๋„ ์ค‘์ง€๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค)(๋” ์ƒ๊ฐ ํ•„์š”)

import kotlinx.coroutines.*
import kotlin.system.*

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        println("The answer is ${concurrentSum()}")
    }
    println("Completed in $time ms")
}

suspend fun concurrentSum(): Int = coroutineScope {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    one.await() + two.await()
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

์ด ๊ฒฝ์šฐ๋Š” scope์—์„œ ์“ฐ๋‹ค ๋ณด๋‹ˆ ์ต์…’์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ์บ”์Šฌ๋œ๋‹ค,์ŠคํŠธ๋Ÿญ์ณ๋“œ ์ปจํฌ๋Ÿฌ์‰ฌ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด์„œ ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค

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) // Emulates very long computation
            42
        } finally {
            println("First child was cancelled")
        }
    }
    val two = async<Int> {
        println("Second child throws an exception")
        throw ArithmeticException()
    }
    one.await() + two.await()
}

์‹คํ–‰-one,two์‹คํ–‰-two์—์„œ ์ถœ๋ ฅ ํ›„ ์ต์…’์…˜ ๋ฐœ์ƒ-์ „ํŒŒ-one์—์„œ finally๋กœ ์—ฐ๊ฒฐ-์ถœ๋ ฅ-์ „ํŒŒ๋กœ ์ธํ•ด ๋ฉ”์ธ์—์„œ catch๋กœ ์ด๋™-์ถœ๋ ฅ

์ฝ”ํ‹€๋ฆฐ5๊ฐ•(์ดํ•ด๊ฐ€ ํž˜๋“  ์šฉ์–ด๋“ค์ด ์ข€ ๋“ค๋ฆผ)

์ฝ”ํ‹€๋ฆฐ์ด ์–ด๋–ป๊ฒŒ ๋Œ์•„๊ฐ€๋Š”์ง€

์ˆœ์ฐจ์ ์œผ๋กœ ์ž‘์„ฑํ–ˆ์Œ์—๋„ ์–ด๋–ป๊ฒŒ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋Š”์ง€

ใ„ดํ•จ์ˆ˜์˜ ๋์— ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํ•˜๋‚˜ ์ถ”๊ฐ€๋˜์–ด ์ปจํ‹ฐ๋‰ด์—์ด์…˜์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ํ˜•ํƒœ๋กœ ๋ณ€๊ฒฝ

ใ„ด์ฝ”๋“œ์—์„œ ์‹คํ–‰ํ• ๋•Œ LABEL์„ ๋„ฃ์–ด์„œ ์ค‘๋‹จ ๋ฐ ์žฌ์ƒ ๊ธฐ์ค€์„ ๋งŒ๋“ฌ

ใ„ดswtich case๋ฌธ ๊ฐ™์€ ๋Š๋‚Œ

ใ„ด์ปจํ‹ฐ๋‰ด์—์ด์…˜..?

ใ„ด์ฝœ๋ฐฑ(?)๊ฐ™์€ ๋Š๋‚Œ

์ฝ”ํ‹€๋ฆฐ java์‹

์ฝ”๋“œ ์“ด ํ›„์— Tools - Kotlin - Show Kotlin Bytecode - ๋””์ปดํŒŒ์ผ

์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ๊ฐ€ ๋ถ„ํ•ด? ๋˜์–ด ๋ณด์—ฌ์ง

switch case๋ฌธ์ด ๋ณด์ธ๋‹ค.

GlobalScope.launch {
    val userData = fetchUserData()
    var userCache = cacheUserData(userData)
    updateTextView(userCache)
}

ใ„ดwhen๋ฌธ ์•ˆ์—์„œ ๊ธฐ์ค€์ด ๋˜๋Š” ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋Š˜๋ ค๊ฐ€๋ฉด์„œ ์ˆœ์ฐจ์  ์‹คํ–‰์ฒ˜๋Ÿผ ๋ณด์ž„

ใ„ด๋˜ํ•œ when๋ฌธ์ด๊ธฐ ๋–„๋ฌธ์— ์ค‘๋‹จ ๋ฐ ์žฌ์ƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค

๊ฒฐ๋ก :์ฝœ๋ฐฑ์„ ๋‚ด๊ฐ€ ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ ์ฝ”ํ‹€๋ฆฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋Š” ๊ฒƒ

(์ด๋ž˜์ €๋ž˜ ์ดํ•ดํ•˜๋ ค๋ฉด ์—ฌ๋Ÿฌ๋ฒˆ ๋ด์•ผํ• ๋“ฏ ํ•˜๋‹ค)

6๊ฐ•

๋””์ŠคํŒจ์ฒ˜

์ฝ”๋ฃจํ‹ด์ด ์–ด๋–ค ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰์‹œํ‚ฌ์ง€ ๊ฒฐ์ •ํ•ด์ฃผ๋Š” ์š”์†Œ

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    launch { // context of the parent, main runBlocking coroutine
        println("main runBlocking      : I'm working in thread ${Thread.currentThread().name}")
    }
    launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
        println("Unconfined            : I'm working in thread ${Thread.currentThread().name}")
    }
    launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher
        println("Default               : I'm working in thread ${Thread.currentThread().name}")
    }
    launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
        println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}")
    }
}

์ฝ”๋ฃจํ‹ด 4๊ฐœ ์‹คํ–‰์ˆœ์„œ:2-3-4-1

2๋ฒˆ:main ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰

3๋ฒˆ:worker-1์—์„œ ์‹คํ–‰

4๋ฒˆ:๋น„์šฉ์ด ๋†’์€.ํ•œ๋ฒˆ ์‚ฌ์šฉ๋งˆ๋‹ค ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ฌ,์‹ค์‚ฌ์šฉ์‹œ์—๋Š” newSingleThreadContext("MyOwnThread").use๋กœ ์“ฐ๋Š”๊ฒŒ ์ข‹์Œ

1๋ฒˆ:runblocking์—์„œ ์˜ต์…”๋„ ํŒŒ๋ผ๋ฏธํ„ฐ ์—†์ด ์‹คํ–‰๋จ->๊ทธ๋Ÿด์‹œ ์ž์‹ ์„ ํ˜ธ์ถœํ–ˆ๋˜ ๊ณณ(๋ฉ”์ธ)์—์„œ ์‹คํ–‰

๋””์ŠคํŽ˜์ฒ˜:์–ด๋””์„œ ์ฝ”๋ฃจํ‹ด์ผ ์‹คํ–‰๋ ์ง€ ์ •ํ•˜๋ฉฐ ์ฝ”๋ฃจํ‹ด ์ฝ˜ํ…์ŠคํŠธ์— ์ €์žฅ๋œ๋‹ค

์ฝ”๋ฃจํ‹ด ์Šค๋ ˆ๋“œ์™€ ๋””๋ฒ„๊น…

import kotlinx.coroutines.*

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

fun main() = runBlocking<Unit> {
    val a = async {
        log("I'm computing a piece of the answer")
        6
    }
    val b = async {
        log("I'm computing another piece of the answer")
        7
    }
    log("The answer is ${a.await() * b.await()}")
}

์ฝ”ํ‹€๋ฆฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ฝ”๋ฃจํ‹ด์„ ๋””๋ฒ„๊น…ํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๊ฐ€ ์žˆ๋‹ค.

log๋ผ๋Š” ํ•จ์ˆ˜๋Š” ์ง€๊ธˆ ์–ด๋””์„œ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค.

๋งŒ์•ฝ ์˜ค๋Š ์ฝ”๋ฃจํ‹ด์—์„œ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ๋ณผ๋ ค๋ฉด jvm option์—์„œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

import kotlinx.coroutines.*

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

fun main() {
    newSingleThreadContext("Ctx1").use { ctx1 ->
        newSingleThreadContext("Ctx2").use { ctx2 ->
            runBlocking(ctx1) {
                log("Started in ctx1")
                withContext(ctx2) {
                    log("Working in ctx2")
                }
                log("Back to ctx1")
            }
        }
    }
}

withcontext๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๊ฐ„์„ ์ ํ”„ํ•  ์ˆ˜ ์žˆ๋‹ค.

use๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ํด๋กœ์ฆˆ ํ•ด์คฌ๋‹ค.(?)

์ฝ˜ํ…์ŠคํŠธ

ใ„ด...(๊ณต๋ถ€ ํ•„์š”)

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    println("My job is ${coroutineContext[Job]}")
}

children

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    // launch a coroutine to process some kind of incoming request
    val request = launch {
        // it spawns two other jobs
        launch(Job()) {
            println("job1: I run in my own Job and execute independently!")
            delay(1000)
            println("job1: I am not affected by cancellation of the request")
        }
        // and the other inherits the parent context
        launch {
            delay(100)
            println("job2: I am a child of the request coroutine")
            delay(1000)
            println("job2: I will not execute this line if my parent request is cancelled")
        }
    }
    delay(500)
    request.cancel() // cancel processing of the request
    println("main: Who has survived request cancellation?")
    delay(1000) // delay the main thread for a second to see what happens
}

์ฝ”๋ฃจํ‹ด์ด ์‹คํ–‰๋ ์‹œ ์ฝ”๋ฃจํ‹ด์€ ๋ถ€๋ชจ์˜ ์ž์‹ ์ฝ”๋ฃจํ‹ด์ด ๋œ๋‹ค.

996์ค„์˜ ์ฝ”๋ฃจํ‹ด์€ ์•ž์„  launch์˜ ์ž์‹์ด ๋˜๋Š” ๊ฒƒ

๋Œ€์‹  globalscope์˜ ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ์ด๋‹ค.

์œ„ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ๋Š” globalscope๋Š” ์˜ˆ์™ธ์˜ ๊ฒฝ์šฐ๋ผ์„œ ๋๊นŒ์ง€ ์‹คํ–‰์ด ๋˜์—ˆ์ง€๋งŒ ์ผ๋ฐ˜ ์ž์‹ ์ฝ”๋ฃจํ‹ด์˜ ๊ฒฝ์šฐ์—๋Š”

๋ถ€๋ชจ๊ฐ€ cancle๋˜์–ด์„œ ์ž์‹๋„ cancle๋˜์—ˆ๋‹ค.

๋ถ€๋ชจ ์ฝ”๋ฃจํ‹ด์˜ ์ฑ…์ž„

๋ถ€๋ชจ ์ฝ”๋ฃจํ‹ด์€ ๋ชจ๋“  ์ž์‹ ์ฝ”๋ฃจํ‹ด๋“ค์ด ์‹คํ–‰๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์คŒ(์ง์ ‘ ํŠธ๋ž™ํ‚น(?) ํ•„์š”์—†์Œ)

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    // launch a coroutine to process some kind of incoming request
    val request = launch {
        repeat(3) { i -> // launch a few children jobs
            launch  {
                delay((i + 1) * 200L) // variable delay 200ms, 400ms, 600ms
                println("Coroutine $i is done")
            }
        }
        println("request: I'm done and I don't explicitly join my children that are still active")
    }
    request.join() // wait for completion of the request, including all its children
    println("Now processing of the request is complete")
}

๋ถ€๋ชจ ์ฝ”๋“œ๊ฐ€ ๋‹ค ์‹คํ–‰๋˜์—ˆ์Œ์„ ์•Œ๋ฆฐ ํ›„์—๋„ ์ž์‹ ์ฝ”๋ฃจํ‹ด์ด ๋๋‚ ๋–„๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ์„ ์•Œ๋ ค์ฃผ๋Š” ์ฝ”๋“œ

์ฝ”๋ฃจํ‹ด ์—˜๋ฆฌ๋จผํŠธ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค๊ธฐ

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    launch(Dispatchers.Default + CoroutineName("test")) {
        println("I'm working in thread ${Thread.currentThread().name}")
    }
}

์—ฌ๋Ÿฌ๊ฐœ์˜ ์ฝ”๋ฃจํ‹ด ์—˜๋ฆฌ๋จผํŠธ(?)๋ฅผ ๋„ฃ๊ณ  ์‹ถ์„๋•Œ๋Š” + ์‚ฌ์šฉํ•˜๊ธฐ,(+๋Š” ์ž์ฒด์ ์œผ๋กœ ๋”ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Œ)

์ฝ”๋ฃจํ‹ด ์Šค์ฝ”ํ”„

import kotlinx.coroutines.*

class Activity {
    private val mainScope = CoroutineScope(Dispatchers.Default) // use Default for test purposes

    fun destroy() {
        mainScope.cancel()
    }

    fun doSomething() {
        // launch ten coroutines for a demo, each working for a different time
        repeat(10) { i ->
            mainScope.launch {
                delay((i + 1) * 200L) // variable delay 200ms, 400ms, ... etc
                println("Coroutine $i is done")
            }
        }
    }
} // class Activity ends

fun main() = runBlocking<Unit> {
    val activity = Activity()
    activity.doSomething() // run test function
    println("Launched coroutines")
    delay(500L) // delay for half a second
    println("Destroying activity!")
    activity.destroy() // cancels all coroutines
    delay(1000) // visually confirm that they don't work
}

ใ„ด์‹คํ–‰(dosomthing)์„ ํ•˜๋‹ค๊ฐ€ ๋ฉˆ์ถ”๋ฉด(destroy) ์‹คํ–‰ ๋ฉˆ์ถ”๊ธฐ(cancle)

์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์„ ์“ฐ๋‹ค๊ฐ€ ๋„๋ฉด์€ ์ž‘์—…์„ ๋ฉˆ์ถ”์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๊ฒƒ์„ ์œ„ํ•ด ์ฝ”๋ฃจํ‹ด ์Šค์ฝ”ํ”„๊ฐ€ ์žˆ๋‹ค.