[Java] synchronized 키워드가 필요한 이유 (예시)

2025. 3. 12. 15:56·Java

상황 가정 + 실패 예시

아래 예시는 좋지 않은 예시이다.

만약 두개의 스레드 각 10000번 돌려 두 스레드 값을 더하여 20000이 나오게 하는 프로그램을 작성한다고 가정하자.

public class SyncTest1BadMain {

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

        Counter counter = new Counter();

        Runnable task = new Runnable(){

            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    counter.increment();
                }
            }
        };

        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();
        System.out.println("결과 : " + counter.getCount());
    }

    static class Counter {
        private int count = 0;

        public void increment() {
            count += 1;
        }

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

위 예시 결과는 아래와 같다. (운이 좋아 20000이 나올 수도 있긴 함)

 


문제점 + 해결 로직

최초에 스레드 두개가 동시에 실행 되면, 두 스레드가 공유 자원의 값을 0으로 읽어버린다.

코드의 흐름이 count 값을 읽어서 계산하는 부분 + 결과를 count 변수에 넣는 두가지 로직으로 구분이 되는데, 서로 공유자원의 값을 계속 덮어 쓰게 된다.

이때 각 스레드가 서로 다른 값을 읽으며 결과 값을 누적해간다면 결과 값을 적절히 얻어올 수 없다. -> 이럴 때 synchronized 키워드가 필요하다

 

public class SyncTest1Main {

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

        Counter counter = new Counter(); // 공유 자원

        Runnable task = new Runnable(){
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    counter.increment();
                }
            }
        };

        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("결과 : " + counter.getCount());
    }

    static class Counter {
        private int count = 0;

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

        public synchronized int getCount() {
            return count;
        }
    }
}

적절히 싱크로나이즈를 사용한 덕분에 몇번을 돌려도 20000이 나오는 것을 확인 할 수 있었다.

'Java' 카테고리의 다른 글

[Java] LinkedList의 특징과 스스로 구현해보기  (0) 2025.06.18
[Java] Optional.filter() vs Stream.filter()  (0) 2025.05.23
[Java] 까먹지 말아야 할 Java 스레드 생명 주기 및 상태 전이  (0) 2025.03.08
[Java] 까먹지 말아야 할 Java 메모리 구조  (0) 2025.03.04
[Java] 채팅 프로그램 소켓 연결 구현 1 - 1 대 1 통신을 해보자  (0) 2025.02.09
'Java' 카테고리의 다른 글
  • [Java] LinkedList의 특징과 스스로 구현해보기
  • [Java] Optional.filter() vs Stream.filter()
  • [Java] 까먹지 말아야 할 Java 스레드 생명 주기 및 상태 전이
  • [Java] 까먹지 말아야 할 Java 메모리 구조
xuv2
xuv2
집에 가고 싶다
  • xuv2
    xuvlog
    xuv2
  • 전체
    오늘
    어제
    • 전체 글 모아보기 (173) N
      • 잡담 (9)
      • 도전 , 자격증 (2)
      • Error (6) N
      • Java (23)
      • Spring (40)
        • Core (10)
        • MVC (21)
        • Thymeleaf (9)
      • DataBase (6)
        • Database Modeling (4)
        • SQL (2)
      • HTTP (11)
      • Network (17)
      • Software Engineering (3)
      • Operating System (3)
      • Algorithm (16)
      • Project (19)
        • Web (9)
        • iOS (8)
        • Python (1)
        • Toy Project (1)
      • A.I (13)
      • Linux (5)
  • 블로그 메뉴

    • 홈
  • 링크

    • Github
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
xuv2
[Java] synchronized 키워드가 필요한 이유 (예시)
상단으로

티스토리툴바