본문 바로가기
Language/JAVA

[자바 멀티스레딩] 동기화: synchronized 과 AtomicInteger 사용법

by YoonJong 2025. 3. 28.
728x90

synchronized로 스레드 간 경쟁 상태(race condition) 을 방지할 수 있다.

 

동기화

- 여러 스레드가 같은 자원에 접근하면 데이터 불일치 발생 가능

- 동기화로 스레드가 순차적으로 자원 접근하도록 제어

- Java에서는 synchronized 을 사용해 구현 가능

 

synchronized

- 메서드나 블록에 적용해 락(Lock) 설정

- 한 스레드가 락을 가진 동안 다른 스레드는 대기

- 락 해제 시 다음 스레드 실행

 

- 과도한 synchronized는 병렬성이 저하되어 성능 문제 가능성 있음

- 데드락 : 여러 락 사용 시 교착 상태 주의

 

 

synchronized 를 사용하지 않고 경쟁 상태 발생할 경우

public class Counter {

    private int count = 0;

    public synchronized void increment() {
        count ++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final count: " + counter.getCount());

    }

}

// 결과값
Final count: 1694

 

 

syncronized 적용 후 

public class Counter {

    private int count = 0;

    public synchronized void increment() {
        count ++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final count: " + counter.getCount());

    }

}

//결과값
Final count: 2000



AtomicInteger 를 사용해서 스레드 안전한 정수 연산을 제공한다.

- 락 없이 원자적 연산으로 동기화 가능 

- CAS ( Compare And Swap ) 알고리즘을 사용

- 단일 연산에서 성능이 우수 ( 복잡한 연산에서는 사용 X )

 

public class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }

    public static void main(String[] args) throws InterruptedException {

        AtomicCounter counter = new AtomicCounter();
        Runnable runnable = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final count: " + counter.getCount());
    }

}

//결과값
Final count: 2000

 

728x90

댓글