달력

12

« 2024/12 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2010. 8. 9. 21:32

Thread - 동기화 기법 JAVA이야기2010. 8. 9. 21:32

자바에는 메소드 전체 영역에 대해 동기화 시키지 않고 일부부만 동기화시킬 수 있도록 하는 기능이 있다.
public void getBusyFlag(){
while(true){
synchronized (this) {
if(busyFlag == null){
busyFlag = Thread.currentThread();
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

플래그가 해제되면 값을 세팅하는 부분만 동기화 시킨다. 이런 사용법은 락을 소유하고 있는 범위가 좀 더 작다는 것을 제외하고는 동기화 메소드의 사용법과 비슷하다.

일반적으로 락의 범위 내에서 그 값을 바꾸는 인스턴스 변수는 동기화 블록을 위한 락 객체로 적합하지 않다.

동기화된 영역 내에 있느 코드는 바로 실행된다.

public synchronized void freeBusyFlag(){
if(getBusyFlagOwner() == Thread.currentThread()){
busyFlag = null;
}
}
private synchronized  Thread getBusyFlagOwner() {
// TODO Auto-generated method stub
return busyFlag;
}

여기서 freeBusyFlag()를 호출하면 getBusyFlagOwner()메소드는 freeBusyFlag()의 동기화된 영역에 포함되어 있기 때문에 락을 해제할 이유가 없다.

$동기화의 범위가 너무 넓으면 데드락에 빠질 수 있다.
public void removeUseless(Folder file){
synchronized (file) {
if(file.isUseless()){
Cabinet directory = file.getCabinet();
synchronized (directory) {
directory.remove(file);
}
}
}
}
public void updateFolders(Cabinet dir){
synchronized (dir) {
for(Folder f = dir.first(); f != null; f = dir.next(f)){
synchronized (f) {
f.update();
}
}
}
}

&&removeUseless() 메소드에서 작업중인Folder객체가 updateFolders() 메소드에 의해 액세스 된다면 어떻게 될까?
updateFolders()는  Cabinet락을 가지고 있고 folder를 원한다(블록킹)
removeUseless는 Folder락을 가지고 있고  Cabinet을 원한다.(블록킹)

무조건 피해라! 발견하기도 어렵다..ㅠ_ㅠ

정적 메소드 초기화
클래스의 각 인스턴스마다 객체 락이 존재하는 것처럼 각 클래스마다 얻어질 수 있는 락이 존재한다. 이 락을 클래스락이라고 부른다. static Method가 호출되면, 프로그램은 메소드를 호출하기 전에 클래스 락을 얻는다. 클래스락을 얻고 메소드를 호출!

'JAVA이야기' 카테고리의 다른 글

Thread - 대기와 통지  (0) 2010.08.10
Java Inner Class  (0) 2010.08.10
Thread - API  (0) 2010.08.06
JAVA - polymorphism  (0) 2010.07.29
10진수를 2진수로 만들어서 요일과 대치하기  (0) 2010.07.23
:
Posted by НooпeУ


Code Start Code End