[카테고리:] 미분류

  • JAVA, Kotlin Codes

    실제 코드로 비교했습니다. 코루틴은 non-blocking으로 효율적이고, 자바 스레드는 blocking으로 리소스 소모가 큽니다. 아래에 각 상황별 코드를 나란히 보여드릴게요.

    1. 네트워크 API 호출 (서버 통신) – 콜백 지옥 vs 순차적 코드

    자바 방식 (콜백 지옥 예시 – Retrofit enqueue)

    api.getPosts(new Callback<List<Post>>() {
        @Override
        public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
            api.getUsers(new Callback<List<User>>() {
                @Override
                public void onResponse(Call<List<User>> call, Response<List<User>> response2) {
                    // 중첩 깊어짐... 에러 처리도 복잡
                }
                @Override public void onFailure(...) { ... }
            });
        }
        @Override public void onFailure(...) { ... }
    });

    코루틴 방식 (순차적처럼 보임)

    viewModelScope.launch {
        try {
            val posts = api.getPosts()  // suspend – 대기하지만 non-blocking
            val users = api.getUsers()
            // 자연스럽게 순차 처리
        } catch (e: Exception) {
            // 한 곳에서 에러 처리
        }
    }

    → 코루틴이 훨씬 가독성 좋고 에러 처리 간단!

    2. 병렬 작업 (여러 API 동시에 호출)

    자바 방식 (ThreadPool + Future)

    ExecutorService executor = Executors.newFixedThreadPool(2);
    Future<String> future1 = executor.submit(() -> { Thread.sleep(1000); return "작업1"; });
    Future<String> future2 = executor.submit(() -> { Thread.sleep(1000); return "작업2"; });
    
    String result = future1.get() + future2.get();  // blocking 대기
    executor.shutdown();

    코루틴 방식 (async/await)

    val deferred1 = async { delay(1000); "작업1" }
    val deferred2 = async { delay(1000); "작업2" }
    
    val result = deferred1.await() + deferred2.await()  // non-blocking

    → 소요 시간 거의 동일 (~1초), 하지만 코루틴 코드가 더 간결하고 스레드 관리 자동.

    3. 대량 동시 작업 (예: 10,000개 요청)

    자바 스레드 → 스레드 하나당 ~1-2MB 메모리 소모 → 10,000개 생성 시 OutOfMemoryError 발생 확률 높음.
    코루틴 → 경량 (몇 KB) → 스레드 몇 개로 수만 개 처리 가능.

    이 차이가 서버-클라이언트에서 가장 크게 체감됩니다 (고동시 네트워크 요청 처리 시 코루틴이 압승).

    4. 안드로이드 UI 업데이트

    자바 방식 (잘못된 예 – 메인 스레드 블로킹)

    new Thread(() -> {
        // 네트워크 호출 (blocking)
        runOnUiThread(() -> updateUI());
    }).start();

    코루틴 방식

    viewModelScope.launch(Dispatchers.IO) {
        val data = api.fetch()  // 백그라운드
        withContext(Dispatchers.Main) {
            updateUI(data)  // 자동 UI 스레드 전환
        }
    }

    → ANR(앱 멈춤) 방지 완벽.

    요약: 코드로 직접 비교해보면 코루틴이 더 간결하고 안전하며 확장성 좋음을 알 수 있어요. 특히 I/O 많은 서버-클라이언트 시나리오에서 빛납니다! 실제 프로젝트에서 한 번 써보시면 차이 확 느껴질 거예요 😊