반응형
멀티 스레드를 잘 사용하기 위해선 동기화 문제를 해결해야 한다.
Java에선 멀티 스레드를 지원하기 위한 구현체를 제공하는데 그 중 Synchronized를 사용하여 동기화와 Critical Section을 사용해보자.
멀티스레드의 동기화를 사용하지 않을 경우
멀티스레드를 구현하는 데 동기화를 사용하지 않는 예제 코드는 아래와 같다.
Thread를 두 개 만들어 멀티 스레드를 구현한 다음, CountCheck의 더하기를 멀티스레드로 실행한다.
Main
package org.example;
public class Main {
public static void main(String[] args) {
TaskRunnuble taskR = new TaskRunnuble();
Thread th1 = new Thread(taskR);
Thread th11 = new Thread(taskR);
th1.start();
th11.start();
}
}
TaskRunnable
public class TaskRunnuble implements Runnable{
CountCheck counter = new CountCheck();
@Override
public void run() {
counter.addValue(3);
}
}
CountCheck
public class CountCheck {
int counter = 100; //공유할자원
public int addValue(int addValue){
for(int i=0; i< 10; i++){
try {
Thread thread = Thread.currentThread();
counter += addValue;
System.out.println(thread.getName()+"더하기" + counter);
Thread.sleep(1000);
} catch (Exception e) {
System.out.print(e);
}
}
return counter;
}
}
원래 정상적인 멀티스레드로 실행할 경우, 더하기가 20번 수행되어 counter의 값이 160이 되어야 한다.
그러나 동기화가 되어 있지 않아, 코드를 실행할 때 스레드가 겹쳐서 더하기가 씹혀버리는 현상이 발생한다.
Synchronized를 사용해 동기화를 했을 경우
Synchronized를 사용하여 임계구역을 지정하면 이러한 동기화 문제를 해결할 수 있으며, 구현 방법은 동기화가 필요한 부분에 Synchronized 키워드를 사용하면 간단하게 해결이 가능하다. 예제 코드에선 CountCheck의 addValue 메소드에 synchronized 키워드를 추가했다.
Main
package org.example;
public class Main {
public static void main(String[] args) {
TaskRunnuble taskR = new TaskRunnuble();
Thread th1 = new Thread(taskR);
Thread th11 = new Thread(taskR);
th1.start();
th11.start();
}
}
TaskRunnable
public class TaskRunnuble implements Runnable{
CountCheck counter = new CountCheck();
@Override
public void run() {
counter.addValue(3);
}
}
CountCheck
public class CountCheck {
int counter = 100; //공유할자원
public synchronized int addValue(int addValue){ //synchronized 키워드 추가
for(int i=0; i< 10; i++){
try {
Thread thread = Thread.currentThread();
counter += addValue;
System.out.println(thread.getName()+"더하기" + counter);
Thread.sleep(1000);
} catch (Exception e) {
System.out.print(e);
}
}
return counter;
}
}
정상적으로 동기화가 된 결과를 확인 가능!
반응형
'Develop > Java' 카테고리의 다른 글
[Java] Concurrent HashMap과 Concurrent List (0) | 2023.05.29 |
---|---|
[Java] Atomic과 CAS(Compare and swap) (0) | 2023.05.29 |
[Java] Synchronized VS Reentrant 차이 (0) | 2023.05.14 |
[Java] Thread란? (0) | 2023.05.14 |
[intellij] gradle 다른 프로젝트 참조(클래스 참조방법) (0) | 2023.05.01 |