Development/JavaEssential

java - synchronized

linuxism 2013. 7. 8. 23:22


자바 애플리케이션이 수행되면 서버나 WAS에 프로세스가 생성된다.
그리고 하나의 프로세스에는 하나이상의 Thread(스레드)가 생성된다. 
단일 스레드가 생성되었다가 종료될 수도 있고 여러개의 스레드가 생성되고 수행되다가 소멸될 수도 있다. 즉 1대多의 관계다.
스레드는 WAS가 관리하며 시스템 개발시에 스레드를 개발자가 직접 컨트롤하는 일은 별로 없으며, 오히려 제대로 알지 못한 상태에서 직접 제어하면 서비스의 안전성에 문제가 생길 수도 있으니 어떤 원리로 작동되는지 정도만 알아도 충분하다고 본다. 

스레드는 같은 프로세스내에서 동일한 데이터를 공유한다. 따라서 하나의 데이터에 대해서 동시에 여러개의 스레드가 접근이 가능하게 되고 그에 따라 데이터의 일관성에 관한 문제가 생길 수가 있다.
그래서 자주 사용되는 것이 synchronized(동기화)이다. 동기화란 하나의 자원(데이터)에 대해서 여러 스레드가 사용하려고 할때 한 시점에서 하나의 스레드만 사용할 수 있도록 하는 것이다.
synchronized 식별자는 보통 메소드의 선언부에 쓰고 이 키워드가 붙은 메소드는 한번에 하나의 스레드만 접근이 가능하며
메소드가 사용중일 때 다른 스레드가 메소드를 호출하면 앞의 스레드가 종료될때까지 기다려야 한다.

이 정도 설명이면 synchronized가 어떤 의미인지는 알 수 있을 것이다.
synchronized는 하나의 객체에 여러개의 객체가 동시에 접근해 처리하는것을 막기위해 사용한다.

public synchronized void exampleMethod() {
//code
...
..
}


private Object obj = new Object();
public void exampleMethod() {
synchronized(obj) {
//code
...
..
}
}


메소드를 동기화하려면 메소드 선언부에 synchronized 식별자를 쓰고, 특정부분을 동기화 하려면 해당 코드 블록에 선언해서
사용하면 된다. 애플리케이션 성능에 있어 이 식별자의 영향력이 막강함에 비해 사용법은 의외(?)로 간단하다.
이말은 거꾸로 해석하자면 synchronized를 잘 알고 쓰면 애플리케이션 자원의 안전성에 득이 되지만 제대로 알지못한 상태에서 남용해서 사용하면 오히려 시스템 성능에 치명적인 독이 될수도 있다는 점을 반드시 인지해야 한다.

그렇다면 어떤 때에 synchronized 식별자를 선언해야 할까?
가장 대표적인 경우이다.

* 하나의 객체에 여러개의 스레드가 접근해서 처리하고자 할때
* static으로 선언한 객체에 여러 스레드가 동시에 사용할때

이런 상황이 발생했을시에 시스템의 안전성 및 데이터의 일관성에 문제가 생길 수 있는 때는 
해당 메소드에 동기화를 부여해야 한다.
어쩌다 한번씩 생길 수 있는 오류라고 해도 개발자라면 항상 참이 될도록 가능한한 튼튼한 구조물을 지어야 하지 않을까...

한마디로 줄이자면,  synchronized... 꼭 필요한때만 사용하자!



출처 - http://finewoo.tistory.com/43