본문 바로가기
IT/자바 Java

자바 스레드와 동기화 쉽게 이해하기 . 실습으로 배우는 병렬 처리

by SidePower 2024. 11. 25.

 

멀티태스킹, 병렬 처리라는 단어 들어봤나요?

컴퓨터가 여러 작업을 동시에 하는 것을 의미하는데,

자바에서는 이걸 스레드(Thread)로 구현할 수 있어요.

 

멀티태스킹의 매력을 느끼게 해주기 위해 오늘은 스레드와 동기화를 배워볼 거예요.

그리고 우리가 직접 타이머 프로그램도 만들어 볼 거예요!

 

스레드란 뭘까?

스레드는 자바 프로그램 안에서 독립적으로 실행되는 작은 작업 단위예요.

여러분이 동시에 여러 일을 할 수 있는 것처럼,

프로그램도 스레드를 통해 여러 작업을 한 번에 실행할 수 있죠.

 

스레드 생성 방법  Thread vs Runnable

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(getName() + ": " + i);
            try {
                Thread.sleep(1000);  // 1초 대기
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        thread1.start();  // 스레드 시작
        thread2.start();
    }
}

위 예제에서는 Thread를 상속해 스레드를 만들었어요.

두 개의 스레드가 동시에 실행되며 1부터 5까지 숫자를 출력합니다.

 

Runnable 인터페이스 구현 예제

class MyRunnable implements Runnable {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());

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

Runnable은 스레드가 아니고 실행 로직을 담는 인터페이스예요.

이렇게 쓰면 자바가 상속 제약 없이 다른 클래스도 상속할 수 있게 도와줘요.

 

스레드 동기화와 안전한 병렬 처리

멀티스레딩에서는 여러 스레드가 같은 자원을 동시에 수정하면 문제가 발생할 수 있어요.

이를 해결하기 위해 synchronized 키워드로 스레드를 동기화해야 해요.

class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) counter.increment();
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) counter.increment();
        });

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

        t1.join();  // t1 스레드가 끝날 때까지 대기
        t2.join();  // t2 스레드가 끝날 때까지 대기

        System.out.println("최종 카운트: " + counter.getCount());
    }
}

여기서는 synchronized 키워드 덕분에

여러 스레드가 동시에 increment()를 호출해도 문제가 생기지 않아요.

간단한 타이머 프로그램 만들기

이번엔 멀티스레딩을 활용한 타이머 프로그램을 만들어볼게요.

이 프로그램은 매초마다 시간이 흐르는 걸 표시합니다.

public class Timer {
    public static void main(String[] args) {
        Thread timerThread = new Thread(() -> {
            int seconds = 0;
            while (true) {
                System.out.println("타이머: " + seconds + "초");
                seconds++;
                try {
                    Thread.sleep(1000);  // 1초 대기
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        timerThread.start();
    }
}

이 프로그램은 매초마다 타이머를 업데이트해요.

종료하려면 수동으로 멈춰야 하지만, 멀티스레딩의 개념을 체험하기엔 딱 좋아요.

반응형

댓글