본문 바로가기

Language, IDE/JAVA, android

[JAVA 자바] synchronized - 스레드 동기화

자바 프로그래밍을 할 때 멀티 스레딩을 하면 각각의 스레드는 독립적으로 동작한다. 하지만 실제 프로그래밍을 할 때에는 스레드들이 

연관 관계를 가지면서 작동해야하는 경우가 많다. 예를들어 스레드들이 현재 접속중인 유저수를 공유해야 하는 경우나 은행에서 예금이나 출금을 하는 경우가 있다. 운영체제에서 배웟듯이 이런 변수들은 동시에 접근하게 되면 문제가 발생하게 된다. 예를들어 3개의 스레드가 동시에 예금을 500원식하면 1500원이 되어야 하는데 모두 0원을 가져와 500을 더해서 저장을하면 500원이 저장되게 된다. 이런 문제를 해결하기 위해서는 동기화를 하여야 한다. 



자바에서는 스레드를 동기화 하기 위해서 synchronized를 제공한다. 스레드는 synchronized 메소드에 들어가기 위해 lock을 얻고 메소드가 끝이나면 lock을 반환한다. 어떠한 스레드가 lock을 얻어 synchronized 메소드를 사용중이면 다른 메소드는 lock이 없으므로 synchronized에 접근할 수 없고 다른 스레드가 lock을 반환 할때까지 기다려야 한다.

쉽게 설명하자면 synchronized 메소드라는 방에 들어가기 위해서는 lock이라는 열쇠가 필요한데 lock은 단 1개만 존재하는 것이다. 어떤 스레드가 lock을 들고 synchronized방에 들어가면 다른 스레드는 synchronized방에 들어갈 열쇠가 없기 때문에 그 스레드가 방에서 나올때 까지 기다려야 하는 것이다. 



이론적으로 말하면 위의 문단에서 말한것과 같지만 실제로 위와같은 작업은 JVM에의해 자동으로 수행된다. 프로그래머는 동기화하기위해 synchronized 메소드를 이용하기만 하면 된다.


synchronized를 이용하는 방법에는 2가지가 있다. 

synchronized method 방법과 synchronized block방법이다.



synchronized method

synchronized 메소드를 사용하는 방법은 간단하다 메소드 앞에 synchronized 키워드를 붙여주면 된다. 


public synchronized 메소드명(파라미터) {

...

}


위의 메소드에는 단 1개의 스레드만이 접속할 수 있다. 주로 공유하는 클래스(객체)에 synchronized 메소드를 구현하고 그 공유 객체를 사용하는 스레드가 해당 메소드를 사용한다.


synchronized block


synchronized(공유할 객체) {

...

}


synchronized 메소드와 기능은 거의 유사하다. 공유할 객체가 파라미터로 들어간다.