fun main() {
println("Hello World!")
}
// 출력 :
Hello World! // 메인 스레드가 println("Hello World!") 실행
Process finished with exit code 0 // 프로세스가 정상 종료
위와 같이 스레드 하나만을 사용해서 실행되는 애플리케이션을 단일 스레드 애플리케이션이라고 한다. 안드로이드에서는 기본적으로 메인 스레드가 존재하며, 메인 스레드 하나만으로도 간단한 안드로이드 앱을 만들 수 있다.
하지만 안드로이드 앱의 기능이 점점 추가된다면 DB 접근, 서버와 통신, 복잡한 연산 등 오래 걸리는 작업을 수행해야 한다. 이럴 때 안드로이드 앱을 메인 스레드만을 사용해서 단일 스레드 애플리케이션으로 만들 수 없다.
만약 위와 같이 메인 스레드에서만 모든 작업을 수행한다면 UI를 그리는 작업을 멈추고 사용자 이벤트 처리를 제대로 하지 못할 것이다. 이는 안드로이드 앱이 멈추거나 버벅이는 원인이 된다.
그래서 이처럼 스레드를 여러 개 사용해서 작업을 처리해야 한다. 이러한 기법을 멀티 스레드 프로그래밍이라고 하며 이를 통해 병렬 처리가 가능해진다. 병렬 처리란 여러 개의 작업을 동시에 실행해서 효율을 높이는 것을 의미한다.
fun main() {
println("[${Thread.currentThread().name}] 메인 스레드 시작")
thread {
println("[${Thread.currentThread().name}] 백그라운드 스레드 시작")
Thread.sleep(2000L) // 2초 동안 대기
println("[${Thread.currentThread().name}] 백그라운드 스레드 종료")
}
Thread.sleep(1000L) // 1초 동안 대기
println("[${Thread.currentThread().name}] 메인 스레드 종료")
}
// 출력
[main] 메인 스레드 시작
[Thread-0] 백그라운드 스레드 시작
[main] 메인 스레드 종료
[Thread-0] 백그라운드 스레드 종료
코틀린 코드로 간단하게 나타내면 다음과 같다. 메인 스레드의 작업과 백그라운드 스레드가 요청받은 작업은 동시에 실행된다.
thread {
val dao = DocumentDatabase.getDatabase(this).documentDao()
val favorites = dao.getAll()
// ...
}
안드로이드 코드를 작성할 때도 이렇게 별도의 스레드를 열어서 작업을 처리할 수 있다. 위의 예시는 Room DB에 접근하는 작업을 별도의 스레드에서 처리하였다. 안드로이드에서도 Room DB 접근은 메인 스레드에서 수행하지 않도록 강제하고 있다. 메인 스레드에서 Room DB에 접근하려고 하면 오류가 발생한다.