ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스레드 기본(3)
    JAVA/in 기초 2014. 3. 5. 01:27
    728x90

    동기화


    스레드의 문제점

    스레드들이 여러 개 동시의 작업을 진행하기 때문에 공유자원의 문제가 발생한다.


    동기화(Synchronization)의 정의

    줄서기(번갈아 가면서 순서대로 공유자원 사용하기)


    동기화의 기법

    synchronized 블록(자원을 사용할 때 자원에 락(Lock)을 거는 방식)

    wait() 와 notify()


    동기화가 보장되지 않는 예제

    public class NotSyncDataMain {
        public static Data data = new Data();
    
        public static void main(String[] args) {
            System.out.println("main 시작");
            Tom t = new Tom();
            Jane j = new Jane();
            t.start();
            j.start();
            System.out.println("main 종료");
        }
    }
    
    class Data {
        public int i = 0;
    }
    
    class Tom extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000000; i++) {
                NotSyncDataMain.data.i++;
            }
            System.out.println("Tom :" + NotSyncDataMain.data.i);
        }
    }
    
    class Jane extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000000; i++) {
                NotSyncDataMain.data.i++;
            }
            System.out.println("Jane :" + NotSyncDataMain.data.i);
        }
    }
    
    결과
    main 시작
    main 종료
    Tom :102920518
    Jane :111359606


    동시에 실행되는 것이 스레드 이기 때문에 Tom과 Jane은 공유자원 Data data의 멤버변수 i의 값을 100000번씩 200000번 증가시킬 것이다. 결과는 200000이 나와야 하지만 전혀 다른 결과가 나온 것을 알 수 있다. 이것은 i에 접근할 때 순서대로 중복되지 않게 번갈아 가면서 작업을 한 것이 아니라 어느 시점에 Tom과 Jane이 동시에 값을 읽고 증가 시켰기 때문에 발생하는 문제 이다.


    동기화 보장 예제

    public class SyncDataMain {
        public static Data data = new Data();
    
        public static void main(String[] args) {
            System.out.println("main 시작");
            Tom t = new Tom();
            Jane j = new Jane();
            t.start();
            j.start();
            System.out.println("main 종료");
        }
    
    }
    
    class Data {
        public int i = 0;
    }
    
    class Tom extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                synchronized (SyncDataMain.data) {
                    SyncDataMain.data.i++;
                }
            }
            System.out.println("Tom :" + SyncDataMain.data.i);
        }
    }
    
    class Jane extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                synchronized (SyncDataMain.data) {
                    SyncDataMain.data.i++;
                }
            }
            System.out.println("Jane :" + SyncDataMain.data.i);
        }
    }
    

    결과

    main 시작

    main 종료

    Tom :1000

    Jane :2000


    동기화 보장을 위한 synchronized 블록 즉 임계 영역을 설정했기 때문에 Tom과 Jane은 동시에 수를 증가시키지는 않느다. 어트 한 시점에 하나의 스레드만이 공유자원의 값을 증가시키기 때문에 최종 결과는 2000 이 나오는 것이다.


    * 다만 동기화를 사용할 경우 임계 영역이 있기 때문에 대기 시간이 많이 발생되고 그로 인해 성능에 악영향을 줄수 있다.



    728x90

    'JAVA > in 기초' 카테고리의 다른 글

    [JAVA8]자바의 다중 상속 관련 내용  (0) 2014.12.19
    [JAVA8]Stream 맛보기  (0) 2014.12.02
    스레드 기본(2)  (0) 2014.03.05
    static 변수는 하나의 프로세스에서 하나의 값만 가진다.  (0) 2014.03.05
    스레드 기본(1)  (0) 2014.03.05
Designed by Tistory.