Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

운기의 블로그

코루틴 - 비동기 / 동시성 본문

안드로이드

코루틴 - 비동기 / 동시성

운띠야 2023. 12. 26. 19:40

이전글 에서는 왜 코루틴이라고 불리는지에 대해서 기본 개념을 알아봤다.

 

이번글에서는

코루틴이 비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴이라고 

설명하는지 알아보려고 한다. 

 

그전에 동시성(동시 실행 설계 패턴)이 무엇인지 비동기가 무엇인지 순서대로 알아보자

비동기와 동시성에 대해서 어느정도 알고 있다는 가정하에 작성해보려고 한다.


동시성이란? 

동시성이라는 용어에 대해서 찾아보면 꼭 같이 나오는 용어가 있는데 바로 병렬성이다.

예전에는 하나의 프로세스에 하나의 스레드일 때는 상상도 할 수 없던 방법이다. 

 

하지만 나날이 성능이 좋아지면서 멀티 프로세스와 멀티스레드가 등장하면서 해당 기법은 중요한 기법으로 자리를 잡았다.

 

동시성은 하나의 프로세스에서 여러작업을 다수의 스레드를 번갈아 가면서 작업하면서 동시에 처리하는거 처럼 보이게 하는 기법이다.

병렬성은 다수의 프로세스에서 다수의 스레드를 이용해서 실제로 동시에 처리하는 기법이다. 

  동시성 병렬성
개념 동시에 처리하는것 처럼 보이게 실제로 동시에 처리
프로세스 수 싱글 프로세스 멀티 프로세스
동작 방식 싱글 프로세스에서 멀티 스레드 멀티 프로세스에서 멀티 프로세스

 

간단히 정리하면 위의 표라고 생각하면된다.


비동기란? 

비동기를 공부할 때 많이 착각하는 부분이 비동기 = 병렬 처리 인거 같다.

실제로 대부분의 설명도 비동기라고 하면 병렬적으로 테스크를 처리한다고 한다.

나 또한 평소에 그렇게 알고 있어서 실제로 병렬로 처리하는 줄 알고 있었다. 

https://mynamewoon.tistory.com/11    (내가 쓴 글)

 

위의 그림처럼 비동기를 수행하는거 처럼 보이지만, 실제로 위의 그림은 정확하게는 병렬 처리하는것이고,

비동기는 중간 중간 스레드 교체를 통해서 위와 같은 처리를 하는것 처럼 보이게 하는것이다.

 

결론 비동기처리는 동시성 처리이다.


코루틴에서 동시성 / 비동기 

 

다시 돌아와서 코루틴 설명을 보면 비동기를 처리하는 동시성 설계 패턴을 가졌다고 한다.

결국 코루틴은 병렬로 처리하는게 아니라 비동기 방식을 보다 쉽게 처리할 수 있도록 만들어 준 거다.

 

안드로이드에 적용해보면

앱을 실행하면 하나의 프로세스가 실행 된다. 

그리고 하나의 프로세스에서 서버 통신이나, 타이머, 디비 접근 과 같이

많은 비동기 처리를 스레드를 번갈아 가면서 코루틴으로 처리할 수 있다.

 

그러면 기존의 비동기처리와는 다른 점이 없다고 느낄 것이다.

그건 비동기의 역사에 대해서 알아보면 왜 코루틴을 사용해야하는가에 대한 답이 나온다.


비동기 역사

비동기를 처리하는데 있어서 개발자들은 항상 갈망해왔던 부분은 비동기를 동기처럼 사용하는 것이였다.

        val user = getUserData()
        textView.text = user.name

 

아래와 같은 방법으로 비동기를 처리할 수 있다면 읽기도 쉽고 쓰기도 쉬울것이다.

하지만 메인스레드에서 서버와 통신하는건 ui를 그리는 메인스레드를 직접적으로 사용하기 때문에 응답이 올 때 까지 

아무런 작업을 하지 못하고 대기하다가 ANR을 발생 시킬 위험도 있다.

 

그렇다면 새로운 스레드에서 한다면?

        Thread{
            val user = getUserData()
            textView.text = user.name            
        }

 

UI는 항상 메인 스레드에서 그려져야한다. 

 

그래서 나온 방법으로는 서버와 응답 후 콜백으로 값을 받아와서 ui를 갱신해주는것이다.

        val user = getUserData { userInfo ->
            textView.text = userInfo.name
        }

 

이러한 방법으로 비동기 처리를 진행했고 안드로이드에서도 retrofit을 사용할 때 매번 callback 함수를 만들어서 리턴해주고는 했다.

하지만 해당 방법의 문제는 user정보를 가져와서 user의 이름으로 다른데이터를 가져오고, 계속해서 콜백안에 콜백이 존재하게 되는 구조가 나타나게 되는데 너무나도 유명한 콜백지옥에 갇히는 것이다. 

 

콜백 지옥은 코드의 가독성을 떨어트리고 심지어 코드를 작성하던 개발자도 넋을 놓는 순간 흐름 놓치는 케이스도 생겼다.

그뿐만 아니라 

        val user = getUserData { userInfo ->
            textView.text = userInfo.name
        }
        
        val car = getCarData { carList ->
            textView.text = carList[0] + user.name
        }

 

콜백으로 받아 온 데이터를 합칠때도 어떤게 먼저 끝날지 알 수 없어서 데이터를 조합하는데 큰 문제가 있었다.

이러한 문제점을 개선한것이 바로 코루틴이다.

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        CoroutineScope(Dispatchers.IO).launch {
            val sum1 = task1(1,2)
            task2(sum1,3)
        }
    }

 

 

코루틴을 통해서 task1 의 값을 서버에서 받아온 후 task2에 sum1을 넣을 수 있다.

드디어 비동기를 동기처럼 쓸 수 있게 된 것이다. 

 

비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴

 

왜 동시 실행 설계 패턴인지, 비동기 처리인지, 코드를 간소화했는지에 대한 의문이 풀렸기를 기도한다.

다음글에서는 안드로이드 개발자 가이드에서 코루틴을 왜 권장하는지에 대해 알아보도록하겠다.

'안드로이드' 카테고리의 다른 글

안드로이드 모듈  (0) 2024.08.18
코루틴 - 기능  (1) 2024.01.01
코루틴 - 코루틴의 뜻  (0) 2023.12.26
안드로이드 - ROOM 사용하기  (0) 2022.05.02
안드로이드 - tableLayout 자동 정렬  (0) 2022.04.09