스레드와 코루틴을 어떻게 사용할까?

김태영·2024년 6월 13일
0

TIL

목록 보기
28/70
post-thumbnail

오늘 공부한 것

- 알고리즘 N개의 최소공배수 풀이
- 스레드와 코루틴 개념 복습
- 개인 과제 lv3

@Volatile 이 뭐지?

강의를 듣던 중 코드에 갑자기 등장한 녀석이다.

companion object {
    @Volatile private var instance: CashShop? = null

    fun getInstance(): CashShop {
        if(instance == null) {
            synchronized(this) {
                instance = CashShop()
            }
        }
        return instance!!
    }
}

@Volatile 은 변수 선언시 사용할 수 있고, 값을 메인 메모리에만 적재할 수 있게 해준다고 한다. 사용하지 않는 경우 스레드는 메인 메모리에서 읽어온 값을 CPU 캐시에 저장하게 되고, 각각의 스레드가 캐시한 값이 달라질 수 있다. 이걸 방지하기 위한 키워드이다.

스레드

스레드는 thread 키워드로 만들 수 있다! 여러 개 만들면 멀티 스레드가 되겠다.

thread(start = true) {
    for(i in 1..10) {
        println("Thread1: 현재 숫자는 ${i}")
        // 비동기 함수
        // 1초의 딜레이 추가
        runBlocking {
            launch {
                delay(1000)
            }
        }
    }
}

코루틴

코루틴은 코루틴 객체를 생성해 만들 수 있다. 코루틴은 빌더라는 것과 같이 사용되는데, 대표적인 빌더로는 launchasync가 있다.

💡 launch vs. async

반환 값이 있는지의 여부로 구분한다. 둘 다 람다 함수의 형태이며, async 함수는 마지막 구문의 실행 결과를 반환한다.

  • launch: 반환 값이 없는 Job 객체
  • async: 반환값이 있는 Deffered 객체
// 코루틴 패키지 import 필요
import kotlinx.coroutines.*

// CoroutineScope: 사용 후 해제 필요
val scope = CoroutineScope(Dispatcher.Default)

// launch나 async라는 함수를 통해 새로운 코루틴을 생성할 수 있다.
val coroutineA = scope.launch { ... }
val coroutineB = scope.async { ... }

// 작업이 끝나면 해제해주어야 한다.
coroutineA.cancel()

// GlobalScope: 해제 필요 X 
val coroutineC = GlobalScope.launch { ... }

// runBlocking을 사용하면 코루틴이 종료될 때까지 메인 루틴 대기
runBlocking {
	launch {
		for (i in 1..5) {
			println(i)
		}
	}
}

// 혹은, Job의 실행이 끝날때까지 대기하는 join() 함수 사용 (야매임)
runBlocking {
  // 코루틴의 결과값이 나올 때까지 대기
	coroutineC.join()
}
profile
화이팅

0개의 댓글