본문으로 바로가기

동기화

category 프로그래밍/java 2017. 9. 15. 22:24

동기화


동기화란 스레드와 스레드 사이의 처리 타이밍 제어 메커니즘을 일컬어 동기화(syncronization)이라고 한다. 



스레드는 매우 편리한 메커니즘이지만, 스레드를 여러개 사용할 때 주의 해야 할 점이 있습니다.
예를 들어, 다음과 같은 경우를 가정해보자, 어떤 자동차 회사에는 운전기사가 2명 있고 각각 돈을 번다. 

그래서 운전 기사를 Driver라는 클래스로 만들고 두 개의 스레드를 운영하는 프로그램을 설계했다. 

2명이 벌어들인 돈은 Company라는 클래스에서 관리한다. 


Sample7.java 스레드가 맏느는 모순


//회사 클래스


class Company


{

    

private int sum = 0;

    

public void add(int a) 송금하는 메소드

    

{

        

int tmp = sum;

        

System.out.println ("현재 금액의 합은 "+ tmp + "원 입니다.");

        

System.out.println (a + "원 벌었습니다.");

        

tmp = tmp + a;

        

System.out.println ("금액의 합을 "+ tmp + " 원으로 만듭니다.");

        

sum = tmp;

    

}


}


// 운전 기사 클래스


class Driver extends Thread


{

    

private Company comp;

    

    


public Driver(Company c)

    

{

        

comp = c;

    

}

    

public void run()

    

{

        

for(int i=0; i<3; i++){

            

comp.add(50); 송금한다. 

        

}

    

}


}



class Sample7


{

    

public static void main(String[] args)

    

{

        

Company cmp = new Company(); 회사 객체를 생성

        

        


Driver drv1 = new Driver(cmp); 운전 기사1 객체를 생성

        

drv1.start();

        

        


Driver drv2 = new Driver(cmp); 운전 기사2 객체를 생성

        

drv2.start();

    

}


}


현현재 금액의 합은 0원 입니다.

현재 금액의 합은 0원 입니다.  이상하다. 0원인데 50원벌었다고 나온다. 

50원 벌었습니다.

금액의 합을 50 원으로 만듭니다.

현재 금액의 합은 50원 입니다.

50원 벌었습니다.

금액의 합을 100 원으로 만듭니다.

현재 금액의 합은 100원 입니다.

50원 벌었습니다.

금액의 합을 150 원으로 만듭니다.

50원 벌었습니다.

금액의 합을 50 원으로 만듭니다.

현재 금액의 합은 50원 입니다.

50원 벌었습니다.

금액의 합을 100 원으로 만듭니다.

현재 금액의 합은 100원 입니다.

50원 벌었습니다.

금액의 합을 150 원으로 만듭니다.


이러한 이유는 여러개의 스레듣가 필드와 같은 공규 자원에 접근할 때 모순이 발생되는 경우가 있다. 

1명의 운전기사(하나의 스레드)가 송금(add()메소드 호출)할 때 다른 운전 기사 또한 동시에 송금을 했기 때문입니다.

회사의 단일 계좌(필드_에 여러 스레드가 동시에 접근해 버린결과 , 충돌이 발생한 것


이러한 문제를 피하기 위해서 한 스레드가 송금하는 동안 다른 스레드가 송금할 수 없도록 막아야 한다. 이를 위해서 송금을 담당하는 add() 메소드를 개선해야 한다. 

public sychronized void add(int a)

{

}


메소드에 synchronized를 붙이면 이 메소드가 스레드에 의해 실행되는 동안, 다른 스레드는 이 메소드를 호출 할 수 없다. 
즉, 어떤 사람의 송금이 끝날 때까지 다른 사람은 기다리는 구조가 되는 것이다. add()메소드에 synchronized를 붙여 보자.


실행결과


현재 금액의 합은 0원 입니다.

50원 벌었습니다.

금액의 합을 50 원으로 만듭니다.

현재 금액의 합은 50원 입니다.

50원 벌었습니다.

금액의 합을 100 원으로 만듭니다.

현재 금액의 합은 100원 입니다.

50원 벌었습니다.

금액의 합을 150 원으로 만듭니다.

현재 금액의 합은 150원 입니다.

50원 벌었습니다.

금액의 합을 200 원으로 만듭니다.

현재 금액의 합은 200원 입니다.

50원 벌었습니다.

금액의 합을 250 원으로 만듭니다.

현재 금액의 합은 250원 입니다.

50원 벌었습니다.

금액의 합을 300 원으로 만듭니다.





'프로그래밍 > java' 카테고리의 다른 글

다양한 애플릿  (1212) 2017.09.19
애플릿(애플릿, 애플릿 뷰어)  (1194) 2017.09.16
쓰레드 생성,동기화  (1202) 2017.09.14
스레드(스레드 기동, 스레드 일시정지)  (1195) 2017.09.12
예외 및 입출력 처리  (1216) 2017.09.11