스레드 두 개 이상이 객체의 데이터 하나에 접근하여 병행성(concurrency)문제가 발생할 수 있다.
즉, 서로 다른 스택 두 개에서 실행되는 메소드가 객체에 있는 동일한 객체에 대한 게터 또는 세터 메소드를 호출하여 데이터의 변조가 일어나게 된다.

이러한 데이터 변조를 막기위해 접근에 관한 락(lock)을 걸어줄 필요가 있다.

어떤 메소드를 한 번에 한 스레드만 접근할 수 있게 하고 싶으면 synchronized라는 키워드를 사용하면 된다.

ex) private synchronized void getNumber(){.....}

synchronized라는 키워드는 "그 동기화된(synchronized) 코드에 접근하려면 스레드가 열쇠를 가지고 있어야" 한다는 것을 의미!

객체의 락에 맞는 열쇠를 가지고 있는 스레드만 동기화된 메소드에 들어갈 수 있으며 락은 메소드마다 하나식 있는 것이 아니고 객체마다 하나식 있다.

동기화된 메소드에 접근하게 되면 열쇠가 있는지 확인하는 과정에서 성능이 저하된다.
또한 병행성이 제한되어 프로그램의 속도가 느려진다. 마지막으로 동기화된 메소드로 인하여 프로그램이 멎어버릴 수 있다.(스레드 교착상태 : thread deadlock)
가능한 한 꼭 동기화해야 할 필요성이 있는 것만 동기화시키고 메소드보다 더 작은 특정 부분만 동기화시키는 것이 좋다.
public void go(){ //메소드 전체를 동기화 하지 않음
 doStuff();
 synchronized(this){//현재 객체(this)에 대해 동기화를 함
  criticalStuff();//해당메소드의 선언부가 아닌 호출부에서 제한적으로 동기화
  moreCriticalStuff();
 }
}

Posted by Taoist
,