ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 스레드
    안드로이드 2020. 5. 9. 16:50
    728x90

    오늘은 많은 분들이 헷갈려하시는 안드로이드에서의 스레드에 대해서 알아볼게요

    멀티스레드에 대해 알아보기 전에 프로세스와 스레드의 차이에 대해 간단하게 알아보고 넘어갈게요.

     

    공통점

    코드를 실행하는 하나의 흐름이다.

    차이점

    스레드 : 스레드간 자원의 공유가 가능하다.

    프로세스 : 프로세스간 자원의 공유가 불가능하다, 프로세스끼리는 완전히 독립적이다.

     

    우리가 C나 자바 프로그램을 실행시키면 main 함수로부터 프로그램이 실행됩니다.

    그리고 이들은 곧 하나의 프로세스이자 하나의 스레드를 가져요

     

    스레드(실행흐름)를 표현한 그림

    이런 프로그램이 있을때 우리는 손가락이나 눈으로 코드를 실타래(빨간줄)처럼 따라가며 결과값을 예측하죠

    이렇게 실타래가 하나인 것을 싱글 스레드라고 불러요. 일반적인 프로그램이죠

     

    멀티스레드는 어떨까요?

    멀티 스레드를 표현한 그림

    맞아요. 실타래가 두 개 이상인것을 멀티스레드라고 불러요.

    보시다시피 결과도 0 ~ 9가 두 번씩 찍히게 됩니다.

     

    스레드는 그럼 자원을 공유하고, 프로세스는 공유하지 못한다고 했는데 자원이 대체 뭘까요?

    자원은 프로그램이 동작하는데 필요한 모든 것들입니다.

    변수, 파일, cpu, 메모리 등 뭐든 될 수 있어요. 프로그래머 입장에서 가장 민감한 자원은 변수겠죠?

     

    즉 스레드는 하나의 전역변수를 두고 여러 스레드가 접근할 수 있는 반면에 프로세스는 접근 불가능하다.

    이 얘기가 곧 완전히 독립적이라는 이야기에요.

    카카오톡 앱과 우리가 만든 앱이 완전히 독립적일 수 있는 이유 또한 각자 앱이 프로세스이기 때문이랍니다.

    스레드 만들어보기

    public class Main {
    
        public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++)
                        System.out.println(i);
                }
            }).start();
        }
    }

    스레드 만드는 법은 간단해요. 위 코드를 따라 치고 실행해보시면 아래와 같은 결과가 나올거에요

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

    정말 간단한데... 이게 스레드가 여러개가 되면 골치아파져요

    공유 자원에 대한 문제가 생기죠

    public class Main {
    
        static int num;
    
        public static void main(String[] args) {
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        num++;
                        System.out.println(num);
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        num++;
                        System.out.println(num);
                    }
                }
            }).start();
        }
    }
    
    결과 : 
    ... 중략
    19991
    19992
    19993
    19994
    19995
    19996
    19997
    19998

    분명 10000까지 도는 for 문 두 개로 num++ 하며 더하면 최종적인 num 값은 20000이 되어야하는데 그렇지 않아요

     

    스레드는 우리 눈으로 보기에는 마치 동시에 실행되는 것처럼 보이지만 사실은 하나의 cpu가 매우 빠르게 왔다갔다 하면서 처리하는거에요

    만화에 보면 매우 빠르게 움직여서 잔상으로 분신을 만드는 그런 연출의 현실판이라고 보시면 됩니다.

     

    num++ 이라는 작업은 내부적으로 세 단계로 나뉘어요

    1. num 값을 가져온다.

    2. num + 1 을 계산한다.

    3. 계산된 값을 변수 num에 저장한다.

     

    스레드 A와 스레드 B가 열심히 for 문을 돌고 있습니다.

    A : 1. num 값을 가져온다.  ( num = 10 )

     

    제어가 B로 넘어간다.

    B : 1. num 값을 가져온다.  ( num = 10 )

    B : 2. num + 1을 계산한다. ( num = 10 여전히.. )

    B : 3. 계산된 값을 변수 num에 저장한다.  ( num = 11 )

     

    제어가 A로 넘어간다. (A는 1번 실행 후 멈춘 상태이므로 2번부터 실행됩니다.)

    A : 2. num + 1을 계산한다.  ( num = 10 )

    A : 3. 계산된 값을 변수 num에 저장한다.  ( num = 11 )

     

    보이시나요? for 문이 각각 1회 실행되어서 num 은 10  ->  12 가 되어야하는데

    지금 num 은 11 밖에 안되어있죠?

     

    스레드 A와 스레드 B가 num 값을 가져오는 순간 이 둘은 서로 다른 레지스터에 값이 저장되기 때문에 이런 문제가 생겨요

     

    정리 : 스레드... 자원 공유는 가능하나.. 쉽지 않다..

     

     

     

     

     

     

    다음 글

    2020/05/09 - [Android & Kotlin] - 안드로이드 멀티스레드

     

    안드로이드 멀티스레드

    2020/05/09 - [Android & Kotlin] - 안드로이드 스레드에이어서 본격적인 멀티스레드에 대해서 알아볼게요 지난 글에서 스레드간에 자원을 공유하는것이 가능은 하나 원하는대로 되지는 않는다는것은 ��

    bubble-dev.tistory.com

     

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

    안드로이드 CountDownTimer  (0) 2020.05.13
    Android AsyncTask  (0) 2020.05.10
    안드로이드 Looper, Message Queue, Handler  (0) 2020.05.09
    안드로이드 핸들러  (0) 2020.05.09
    안드로이드 멀티스레드  (0) 2020.05.09

    댓글

Designed by Tistory.