억대 연봉을 위한 인간수업
article thumbnail
반응형

멀티 스레드를 잘 사용하기 위해선 동기화 문제를 해결해야 한다.

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;
    }
}

 

정상적으로 동기화가 된 결과를 확인 가능!

반응형
profile

억대 연봉을 위한 인간수업

@회뜨는참치

이 글이 당신에게 조금이라도 도움이 된다면 좋겠습니다.