program instructions that performs a specific task, packaged as a unit In different programming languages, a subroutine may be called a procedure, a function, a routine, a method, or a subprogram. The generic term callable unit is sometimes used. : https://en.wikipedia.org/wiki/Subroutine
coroutine in 1958 when he applied it to construction of an assembly program. The first published explanation of the coroutine appeared later, in 1963 : https://en.wikipedia.org/wiki/Coroutine
multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes. : https://en.wikipedia.org/wiki/Coroutine
light-weight thread. The biggest difference is that coroutines are very cheap, almost free: we can create thousands of them, and pay very little in terms of performance. Light-weight thread.
} @Test fun test() { println("run") CoroutineScope(Dispatchers.Default).launch { (0..10).forEach { val sum = (it..10).toMutableList().sum() println(sum) } } println("wait") runBlocking { delay(500L) } println("Test end") } 1. 500 ms ӝ 3. 500 ms ӝ റ Test end 2. 500 ms زউ 0..10ਸ ؊ೞח sum प೯
Int { val ret = this.sumBy { it } delay(100) return ret } @Test fun test() { println("run") CoroutineScope(Dispatchers.Default).launch { (0..10).forEach { val sum = (it..10).toMutableList().sum() println(sum) } } println("wait") runBlocking { delay(500L) } println("Test end") } दрਵ۽ח ഛೞ ঋ ۽ delay ਊ run wait 55 55 54 52 Test end
Int { val ret = this.sumBy { it } delay(100) return ret } @Test fun test() { println("run") (0..10).forEach { val sum = (it..10).toMutableList().sum() println(sum) } } println("wait") runBlocking { } println("Test end") } run wait 55 55 54 52 Test end CoroutineScope(Dispatchers.Default).launch { delay(500L) job.join() val job =
this might be heavy CPU-consuming computation or async logic, we'll just send five squares for (x in 1..5) channel.send(x + x) } // here we print five received integers: repeat(5) { println(channel.receive()) } println("Done!") 2 4 6 8 10 Done!
{ select<Unit> { // <Unit> means that this select expression does not produce any result fizz.onReceive { value -> // this is the first select clause println("fizz -> '$value'") } buzz.onReceive { value -> // this is the second select clause println("buzz -> '$value'") } } } fun CoroutineScope.fizz() = produce<String> { while (true) { // sends "Fizz" every 300 ms delay(300) send("Fizz") } } fun CoroutineScope.buzz() = produce<String> { while (true) { // sends "Buzz!" every 500 ms delay(500) send("Buzz!") } } val fizz = fizz() val buzz = buzz() repeat(7) { selectFizzBuzz(fizz, buzz) } coroutineContext.cancelChildren() // cancel fizz & buzz coroutines fizz -> 'Fizz' buzz -> 'Buzz!' fizz -> 'Fizz' fizz -> 'Fizz' buzz -> 'Buzz!' fizz -> 'Fizz' buzz -> ‘Buzz!'
coroutine println("main runBlocking : 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}") } ೞ ঋওӝী ৻ࠗ currentThreadী ٮܲ. Work threadীࢲ ز Work thread۽ ࢜۽ MyOwnThreadܳ ࢤࢿ
Job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onDestroy() { super.onDestroy() job.cancel() } } Android Coroutines onDestroy()에서 job을 종료하도록 한다. Job을 미리 생성하여 CoroutineContext에 미리 지정 할 수 있다. Activity에서 사용할 기본 Context를 정의한다.
누른다 애니메이션을 실행(Progress)/버튼 비활성화 완료하면 애니메이션 종료/버튼 활성화 문제 1. 버튼 비활성화 네트워크 시도 중 오류 발생에 따른 버튼 활성화가 쉽지 않음 문제 2. RxJava 활용으로 버튼 비활성화 대신 시간을 지정 일정 시간마다 버튼이 눌릴 수 있어 결국 중복 이벤트 발생 문제 3. 원하는 이벤트 종료 때까지 애니메이션 처리 사용자 거부감
val event = GlobalScope.actor<View>(Dispatchers.Main) { for (event in channel) action(event) } setOnClickListener { event.offer(it) } } var currentIndex = 0 fab.onClick { 10.countDown(currentIndex++) } 1. Singletone의 GlobalScope 활용 2. actor 이용 event 받기 3. actor에 offer로 event 보내기 4. 받은 event를 Higher-Order function으로 넘겨서 정의하도록 한다. 6. 람다 표현으로 countDown 구현 5. 이때 Higher-Order function 정의는 suspend가 포함되어야 한다