chapter12. 멀티 스레드.


12.4 동기화 메소드와 동기화 블록

12.4.1 동유 객체를 사용할 때의 주의할 점

// 싱글 스레드 프로그램에서는 한 개의 스레드가 객체를 독차지해서 사용하면 되지만,

// 멀티 스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 하는 경우가 있다.


- 멀티 스레드가 하나의 객체를 공유하므로해서 생기는 오류



12.4.2 동기화 메소드 및 동기화 블록 - synchronized

// 스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없도록 하려면 스레드 작업이 끝날 때 까지 객체에 잠금을 걸어서

다른 스레드가 사용할 수 없도록 해야 한다

// 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역을 임계 영역이라고 한다.

// 자바는 임계 영역을 지정하기 위해 동기화(synchronized) 메소드와 동기화 블록을 제공한다

// 스레드가 객체 내부의 동기화 메소드 또는 블록에 들어가면 즉시 객체에 잠금을 걸어

다른 스레드가 임계 영역 코드를 실행하지 못하도록 한다

// 동기화 메소드를 만드는 방법은 다음과 같이 메소드 선언에 synchronized 키워드를 붙이면 된다.

// synchronized 키워드는 인스턴스와 정적 메소드 어디든 붙일 수 있다.

// 동기화 메소드는 메소드 전체 내용이 임계 영역이므로 스레드가 동기화 메소드를 실행하는 즉시 객체에는 잠금이 일어나고,

스레드가 동기화 메소드를 실행 종료하면 잠금이 풀린다.


- 단 하나의 스레드만 실행할 수 있는 메소드 또는 블록을 말한다

- 다른 스레드는 메소드나 블록의 실행이 끝날 때까지 대기해야 한다 (스레드가 동기화 메소드를 실행 종료하면 잠금이 풀린다)



 - 동기화 메소드

 




 - 동기화 블록 (일부 내용만 임계 영역으로 만들고 싶다면)





메인 스레드가 실행하는 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package sec04.exam01_unsynchronized;
 
public class MainThreadExample {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        
        User1 user1 = new User1(); // User1 스레드 생성
        user1.setCalculator(calculator); // 공유 객체 설정
        user1.start(); // User1 스레드 시작
 
        User2 user2 = new User2(); // User2 스레드 생성
        user2.setCalculator(calculator); // 공유 객체 설정
        user2.start(); // User2 스레드 시작
    }
}
cs

공유 객체 (수정 전)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package sec04.exam01_unsynchronized;
 
public class Calculator {
    private int memory;
 
    public int getMemory() {
        return memory;
    }
 
    public void setMemory(int memory) { // 계산기 메모리에 값을 저장하는 메소드
        this.memory = memory; // 매개값을 memory 필드에 저장
        try {
            Thread.sleep(2000); // 스레드를 2초간 일시정지 시킴
        } catch(InterruptedException e) {}    
        System.out.println(Thread.currentThread().getName() + ": " +  this.memory);
    }
}
cs


유 객체 (동기화 메소드로 수정)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package sec04.exam02_synchronized;
 
public class Calculator {
    private int memory;
 
    public int getMemory() {
        return memory;
    }
 
    public synchronized void setMemory(int memory) {
        this.memory = memory;
        try {
            Thread.sleep(2000);
        } catch(InterruptedException e) {}    
        System.out.println(Thread.currentThread().getName() + ": " +  this.memory);
    }
}
cs

User1 스레드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package sec04.exam01_unsynchronized;
 
public class User1 extends Thread {    
    private Calculator calculator;
    
    public void setCalculator(Calculator calculator) {
        this.setName("User1"); // 스레드 이름을 User1로 설정
        this.calculator = calculator; // 공유 객체인 Calculator를 필드에 저장
    }
    
    public void run() {
        calculator.setMemory(100); // 공유 객체인 Calculator의 메모리에 100을 저장
    }
}
cs

User2 스레드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package sec04.exam01_unsynchronized;
 
public class User2 extends Thread {    
    private Calculator calculator;
    
    public void setCalculator(Calculator calculator) {
        this.setName("User2"); // 스레드 이름을 User2로 설정
        this.calculator = calculator; // 공유 객체인 Calculator를 필드에 저장
    }
    
    public void run() {
        calculator.setMemory(50); // 공유 객체인 Calculator의 메모리에 50을 저장
    }
}
cs




Posted by 너래쟁이
: