- '이것이 자바다'의 12장의 예제를 참고하여 실습한 내용입니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class SynchronizedCalculator {
private int memory;
public int setMemory(int memory) {
this.memory = memory;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + " = " + this.memory);
return this.memory;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class SynchronizedUser1 extends Thread {
private SynchronizedCalculator synchronizedCalculator;
private int memory = 0;
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public void setSynchronizedCalculator(SynchronizedCalculator synchronizedCalculator) {
this.setName("User1");
this.synchronizedCalculator = synchronizedCalculator;
}
@Override
public void run() {
memory = synchronizedCalculator.setMemory(memory);
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class SynchronizedUser2 extends Thread {
private SynchronizedCalculator synchronizedCalculator;
private int memory = 0;
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public void setSynchronizedCalculator(SynchronizedCalculator synchronizedCalculator) {
this.setName("User2");
this.synchronizedCalculator = synchronizedCalculator;
}
@Override
public void run() {
memory = synchronizedCalculator.setMemory(memory);
}
}
|
cs |
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
|
@Test
@DisplayName("동기화 메소드로 공유 객체 사용")
void multiThreadSynchronizedArea() {
SynchronizedCalculator synchronizedCalculatorlc = new SynchronizedCalculator();
SynchronizedUser1 user1 = new SynchronizedUser1();
user1.setMemory(100);
user1.setSynchronizedCalculator(synchronizedCalculatorlc);
user1.start();
SynchronizedUser2 user2 = new SynchronizedUser2();
user2.setMemory(50);
user2.setSynchronizedCalculator(synchronizedCalculatorlc);
user2.start();
try {
Thread.sleep(3000);
}catch (Exception e) {
}
assertAll(
() -> assertThat(user1.getMemory()).isEqualTo(100),
() -> assertThat(user2.getMemory()).isEqualTo(50)
);
}
|
cs |
- 중간에 Thread.sleep(3000);을 넣은 이유는 동기화 테스트를 위해 만든 클래스들이 임계영역에 동시에 접근하는 부분을 확인하기 전에 테스트 메서드가 종료되는 문제가 있어서 넣었습니다.
- 우선 SynchronizedCalculator 클래스에서 콘솔에 출력해주는 것을 보면
- SynchronizedUser1 클래스를 먼저 호출 했지만 User2 스레드부터 확인 할 수 있다
- 이것은 컨택스트 스위칭에 의해 달라진다
- 테스트 결과를 보면
- SynchronizedUser1 클래스를 수행한 결과 100 이라는 값을 예상하고 있지만 실제 결과는 50 이기에 테스트를 실패했다
- SynchronizedUser2 클래스는 수행한 결과값을 50 이라고 예상하고 있는데 실제 결과도 50 이 나왔기에 테스트를 통과해서 오류로 보이는 메시지가 없다
- 이 테스트를 통해서 임계영역의 문제를 해결하지 않게 된다면 값의 일관성을 보장할 수 없다는 것을 알 수 있다
'Java' 카테고리의 다른 글
Java Garbage Collection(GC)란 무엇이고 동작방식과 G1GC에 대해 (0) | 2022.05.08 |
---|---|
JVM 구조와 Java의 실행방식 (0) | 2022.05.07 |
Java char타입의 초기화를 할 때 '' 불가한 이유 (0) | 2022.04.02 |
Java GC 처리방법 (0) | 2022.04.01 |
Java 제네릭 (0) | 2022.02.07 |