스레드와 동시성 프로그래밍

2023. 11. 11. 23:52개발 문서/Java

728x90
반응형

스레드(Thread)는 프로세스 내에서 독립적으로 실행되는 가장 작은 단위입니다. 자바에서는 Thread 클래스를 이용하여 스레드를 생성하고, Runnable 인터페이스를 구현한 객체를 Thread에 전달하여 스레드를 실행할 수 있습니다.

스레드 생성과 실행:

class MyThread extends Thread {
    public void run() {
        // 스레드가 실행할 코드
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getId() + " Value " + i);
        }
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        // 스레드 객체 생성
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        // 스레드 실행
        thread1.start();
        thread2.start();
    }
}

Runnable 인터페이스를 이용한 스레드:

class MyRunnable implements Runnable {
    public void run() {
        // 스레드가 실행할 코드
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getId() + " Value " + i);
        }
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        // Runnable 객체 생성
        MyRunnable myRunnable = new MyRunnable();

        // 스레드 생성 및 실행
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);

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

동기화(Synchronization):

여러 스레드가 공유 자원에 동시에 접근할 때, 예측할 수 없는 결과가 발생할 수 있습니다. 이를 방지하기 위해 동기화가 필요합니다.

class Counter {
    private int count = 0;

    // synchronized 키워드를 사용하여 메소드 동기화
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

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

        // 여러 스레드가 동시에 increment() 메소드를 호출
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

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

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

        // 모든 스레드의 실행이 끝날 때까지 기다림
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

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

데드락(Deadlock)과 스레드 안전성:

동시성 프로그래밍에서 주의해야 할 문제 중 하나는 데드락입니다. 데드락은 두 개 이상의 스레드가 서로 상대방의 작업이 끝날을 기다리면서 서로를 블록하는 상황입니다. 데드락을 방지하려면 스레드들이 자원에 접근할 때 일관된 순서를 유지하거나, 자원을 동시에 접근하는 것을 피해야 합니다.

스레드 안전성(Thread Safety)은 여러 스레드에서 동시에 호출되어도 안전하게 동작하는 것을 의미합니다. 동기화를 통해 스레드 안전성을 유지할 수 있습니다.

스레드와 동시성 프로그래밍은 복잡하고 예측하기 어려운 문제를 초래할 수 있습니다. 따라서 스레드의 안전성과 데드락 등을 고려하여 프로그램을 설계하고 구현하는 것이 중요합니다.