EnjoyLife

아직도 스레드를 아직도 사용하는 개발자들에게 고함 본문

안드로이드 개발/개발팁

아직도 스레드를 아직도 사용하는 개발자들에게 고함

Aiden96 2025. 3. 27. 10:49

제발  코루틴으로 바꿔주세요. ㅠㅠ 

제가 마주한 앱이 아래 유형의 앱이라 절망에 빠져 글을 상소문을 올립니다. 

 

아직도 자바+ 스레드+ 콜백지옥+ 액티비티 몰빵(api 로직,데이터로직,UI로직) 형식으로 구현됨. 

 

코루틴과 워크매니저는  아래 상황일때 적절하게 골라서 사용하세요. 

상황추천 방식
일반적인 백그라운드 작업 ✅ Coroutine (Dispatchers.IO)
여러 작업을 순차 or 병렬 처리 ✅ Coroutine + launch {} or async {}
앱이 종료되어도 작업 유지해야 함 ✅ WorkManager
Java 기반에서 코루틴 도입이 어려움 ✅ ExecutorService
아주 단순한 Handler 메시지 처리 ⚠ HandlerThread (지양하지만 가능)

 

❗ Thread 직접 사용의 치명적인 문제점들

1.  메모리 낭비 및 누수 위험

  • Thread는 생성할 때마다 OS 스레드를 하나 직접 생성함.
  • 너무 많은 스레드를 만들면 메모리 폭주, OutOfMemoryError 발생 가능.
  • 코루틴은 내부적으로 스레드 풀을 공유하며, 수천 개의 코루틴도 가볍게 실행 가능
for (int i = 0; i < 1000; i++) {
    new Thread(() -> {
        // 메모리 폭탄 주의!
    }).start();
}

2. 스레드 종료·취소 관리가 어렵다

  • Thread는 시작하면 중간에 중단(cancel) 시키기 어려움.
  • 강제로 중단하려면 interrupt() 등을 써야 하는데, 예외 처리도 복잡하고 위험함.
  • 반면, 코루틴은 job.cancel()로 안전하고 우아하게 취소 가능함.

3. 코드가 지저분하고 유지보수가 어려움

  • Thread, Runnable, Handler, Callback 구조는 중첩 코드, 콜백 지옥을 유발함.
  • 코루틴은 suspend, async, launch로 비동기 코드를 동기처럼 깔끔하게 작성 가능.

4. 예외 처리 어려움

  • Thread 안에서 예외가 발생하면, 앱 전체 크래시로 이어질 수 있음.
  • 코루틴은 try-catch, CoroutineExceptionHandler 등으로 예외 처리를 안전하게 할 수 있음.

5.  라이프사이클과 연동 불가능

  • Thread는 액티비티나 프래그먼트가 종료돼도 계속 돌 수 있음 → 메모리 누수 + 크래시 유발.
  • lifecycleScope.launch 같은 코루틴은 액티비티가 종료되면 자동 취소됨 → 매우 안전함.

6.  테스트 어려움

  • Thread.sleep() 같은 코드가 있으면 테스트가 느리고 불안정해짐.
  • 코루틴은 TestCoroutineDispatcher 등으로 빠르고 안정적인 테스트 가능.

1. 왜 스레드 대신 코루틴을 써야 하는가? 

ThreadCoroutine

 

   항목                                                            스레드                               코루틴     
스레드 관리 수동, 복잡 자동, 경량
메모리 효율 낮음 매우 좋음
예외 처리 위험 안전
코드 구조 복잡 깔끔
취소 처리 어려움 쉽게 가능
라이프사이클 연동 불가능 가능 (lifecycleScope 등)

2.언제 Thread를 꼭 써야 할까?

  • 정말 필요한 저수준 OS 작업, 또는 JNI 연동 등에서만 예외적으로 고려됨.
  • 일반적인 안드로이드 앱 개발에서는 거의 코루틴 또는 WorkManager로 충분합니다. 

뭐니 뭐니해도  Coroutine 

  • Thread 대신 가장 많이 쓰이는 현대적인 방법.
  • 메모리/스레드 효율 좋고, 코드도 간결하며 에러 관리도 좋음.
viewModelScope.launch(Dispatchers.IO) {
    // 백그라운드 작업
}

 

언제 쓰면 좋을까요?

  • 비동기 작업, 네트워크, 디스크 IO, 타이머, 반복 작업 등
  • UI와 관련된 작업을 Main / IO 스레드로 쉽게 분리하고 싶을 때