day 12. 멀티쓰레드.
강의/부캠 안드로이드 학습정리

day 12. 멀티쓰레드.

설계 패턴은 어떤 상황에서 어떤 구조를 갖도록 설계하고 구현하면 되는지 문제 해결 과정의 경험을 모아놓은 것이다. 대부분 디자인 패턴은 특정한 상황에서 문제점을 해결하는 구조를 고민해서 나온 결과라는 것이다. 

 

비동기 실행 Coroutine

https://umbum.dev/595

 

[Kotlin] by : Decorator & Delegation

상속을 허용하지 않는 클래스에 새로운 동작을 추가해야 할 때(Wrapping) 또는 메소드의 동작을 변경하고 싶을 때 데코레이터 패턴을 사용하게 되는데 단점이 준비 코드가 너무 많이 필요하다는

umbum.dev

https://medium.com/@limgyumin/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%BD%94%EB%A3%A8%ED%8B%B4%EC%9D%98-%EA%B8%B0%EC%B4%88-cac60d4d621b

 

코틀린 코루틴의 기초

코틀린 의 코루틴은 비동기 프로그래밍을 처리할수 있는 좋은 방법입니다.

medium.com

 

https://todaycode.tistory.com/23

 

[kotlin] 코루틴 공부하기 (비동기 처리, 서버 딜레이 처리)

빌어먹을 코루틴... 저번에 공부하다가 도저히 못해먹겠어서 포기했다가 오늘 다시 도전했다. 항상 느끼는 거지만 아무것도 모를 땐 그렇게 어렵게 느껴지다가 또 막상 성공하면 아 이걸 왜 이

todaycode.tistory.com

 

 

이론에서 배울 땐 원래 코드 한줄 한줄 밑으로 내려가며 실행되어야 하지만 멀티스레드로 변경하면 그런거 없이 무시하고 쭉 실행하는 방식으로 간다. 그래서 밑의 경우를 보면 start와 end가 먼저 출력됨. 다른 예시들도 살펴보면 launch를 할 때마다 그거를 실행하는 쓰레드가 생기는 것 같다.

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { doWorld() }
    println("Hello")
}

// this is your first suspending function
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}
        runBlocking {
            println("Async Start: ${LocalDateTime.now()}")
            launch { postEvent(publisher, hmss) }
            println("Async End: ${LocalDateTime.now()}")
        }

 

그리고 사실 이렇게 쓰레드를 만들어서 관리하는게 너무너무 힘들다 보니까 os가 알아서 관리하도록 하고 코드에선 Queue를 만들어 가상의 쓰레드로 만들어서 동작하도록 했다. 실제로는 os가 알아서 쓰레드 나눠서 처리하고 코드에선 마치 쓰레드로 나누는 것 처럼 느껴지게 만든 것.

실제 println 찍어보면 Queue로써 관리되고 Queue에는 있지만 쓰레드에서 실행하기엔 element가 없어 empty 상태면 empty라고 뜨는걸 볼 수 있다.

앞으로 기술이 발전하면서 cpu의 hz 속도도 증가하지만 cpu core수도 증가해서 멀티쓰레드를 사용하는게 더더욱 중요해질 것이고 실제로도 많은 라이브러리에서 멀티쓰레드를 사용하고 있다고 한다.

 

 

  • Observer 패턴과 Publisher-Subscriber 패턴을 구분해보고 차이점과 공통점을 토론한다.

https://jistol.github.io/software%20engineering/2018/04/11/observer-pubsub-pattern/

https://zorba91.tistory.com/291

 

Observer는 subject와 상호작용하며 서로한테 알릴 때 중간에 매개체가 없다는 거고 publisher-subscriber는 event-channel이라는 중간 매개체가 있다. 그래서 event-channel이 비동기적으로 "이런 일이 있었다" 라고 알려줄 수 있는듯.

 

 


클래스 생성자 초기화

class Publisher (private val name: String?) {

if null이면 nil

var senderName = sender?.getName() ?: "nil"

https://gist.github.com/Greenddoovie/83e7c5c7a0cca59da45b07796ae9f426

 

 

 

 

CoroutineScope(Dispachers.Unconfined).launch{ }

Unconfined는 main 쓰레드가 종료되었을 때 실행해라.

Unconfined는 이어서 쓰지만 Default는 새로 쓴다.

launch는 주로 동기, async는 주로 비동기 할 때 사용된다.

끝날때까지 나가지 않도록 runBlocking, .join(), .await()

Queue를 넣은 이유가 어차피 늦게 알려도 되니까 넣은거 아닐까.

 

runBlock은 잘 안쓴다. 다 실행해준다는 보장이 있지만 느려지거나 해서 안쓰는듯. 정석은 CoutineScope를 정의해서 사용하는 것.

 

LiveData는 MVC 패턴에서 view는 그림UI만 하고 어떻게 그릴지는 viewmodel에서 data를 저장하게 된다. 뭘 쓰고 출력해라. view는 내용을 올리는것만 되어있고 어떤걸 올릴지는 viewmodel이 가지고 있다. 뭘 누르면 행동하는 로직이 viewmodel안에 있는데 연동해서 자동으로 바꿔주는게 livedata.

livedata가 overserver와 비슷한 것 같다. 변경되면 반영되서 작동되고.

 

livedata view가 해당 뷰가 아니면 데이터가 변화가 있어도 observing을 안하고 저장만 하고 있다가 해당 뷰가 되면 반영된다. 그래서 view의 lifecycle를 인지한다.

 

coroutine을 해서 디버그를 하려면 이름을 지어서 할 수 있긴 하다. 너무 어려워서 문제지만..

 

publisher랑 subscriber는 서로 존재를 모르고, 호출할 수도 없지만 중간 매개체가 다 알아서 자기가 다 한다.