본문 바로가기
프로그래밍/JAVA

초보 자바 프로그래밍(57) - Thread

by 머니테크리더 2023. 10. 3.
반응형

초보 자바 프로그래밍(56) - Thread
초보 자바 프로그래밍(56) - Thread

 

 

🔖 INDEX

     

     

    Thread (스레드) 개념

    Java는 멀티 스레딩을 지원하는 프로그래밍 언어입니다. 이를 통해 개발자는 동시에 여러 작업을 수행할 수 있게 됩니다.

     

    Thread (스레드)란?

    스레드는 컴퓨터 프로그램 내에서, 특히 프로세스 내에서 실행되는 가장 작은 단위의 처리입니다. 스레드는 동일한 프로세스의 메모리를 공유하면서 독립적으로 실행될 수 있습니다. 이를 통해 여러 작업을 병렬로 처리하거나 비동기적으로 처리하는 것이 가능해집니다.

     

    스레드의 중요성

    • 동시성: 멀티스레드를 활용하면 하나의 프로세스 내에서 여러 작업을 동시에 수행할 수 있습니다. 이는 특히 I/O 바운드 작업이 많은 프로그램에서 성능 향상을 가져올 수 있습니다.
    • 자원 공유: 스레드는 동일한 프로세스 내에서 메모리와 리소스를 공유하기 때문에 효율적인 자원 사용이 가능합니다. 하지만 이로 인한 동시성 문제도 발생할 수 있습니다.
    • 응답성 향상: 멀티스레드 프로그램에서 하나의 스레드가 블록되거나 지연되더라도 다른 스레드는 계속 실행될 수 있습니다. 이로 인해 사용자 경험이 향상됩니다.

     

    스레드 vs 프로세스

    • 메모리 공간: 프로세스는 독립적인 메모리 영역을 가지지만, 스레드는 같은 프로세스 내에서 메모리를 공유합니다.
    • 통신 방법: 스레드 간의 통신은 메모리를 공유하기 때문에 비교적 간단하지만, 프로세스 간의 통신은 IPC(Inter-Process Communication) 메커니즘을 필요로 합니다.
    • 생성 및 종료 비용: 스레드의 생성 및 종료 비용은 프로세스보다 훨씬 적습니다.
    • 영향 범위: 스레드 하나가 비정상 종료될 경우, 동일한 프로세스 내의 다른 스레드에 영향을 줄 수 있습니다. 반면, 하나의 프로세스가 비정상 종료되더라도 다른 프로세스에는 영향을 주지 않습니다.

     

    스레드의 동시성 문제

    스레드가 메모리와 리소스를 공유하면서 동시에 실행되기 때문에 동시성 문제가 발생할 수 있습니다. 예를 들어, 두 스레드가 동시에 같은 데이터를 변경하려고 할 때 발생하는 '경쟁 조건(race condition)'이 있습니다. 이러한 문제를 해결하기 위해서는 동기화 메커니즘, 락(lock) 등의 방법을 사용해야 합니다.

     

     

    Java에서의 Thread (스레드)

    스레드 생성하기

    Java에서 스레드를 생성하는 방법은 크게 두 가지입니다:

     

    Thread 클래스를 상속받기

    Thread 클래스를 상속받아 run() 메서드를 오버라이드합니다.

    class MyThread extends Thread {
        public void run() {
            // 스레드가 실행할 코드
        }
    }

     

    Runnable 인터페이스 구현하기

    Runnable 인터페이스를 구현하고 run() 메서드를 오버라이드합니다.

    class MyRunnable implements Runnable {
        public void run() {
            // 스레드가 실행할 코드
        }
    }

     

    스레드 시작하기

    스레드를 시작하기 위해서는 start() 메서드를 호출합니다.

    MyThread thread1 = new MyThread();
    thread1.start();
    
    Thread thread2 = new Thread(new MyRunnable());
    thread2.start();

     

    스레드 우선순위

    스레드는 우선순위를 가집니다. 이는 스케줄러에 의해 어떤 스레드가 더 많은 CPU 시간을 받을지 결정하는데 사용됩니다.

    • Thread.MIN_PRIORITY (1)
    • Thread.NORM_PRIORITY (5)
    • Thread.MAX_PRIORITY (10)

    우선순위를 설정하기 위해서는 setPriority() 메서드를 사용합니다.

    thread1.setPriority(Thread.MAX_PRIORITY);

     

    스레드 동기화

    멀티 스레드 환경에서는 여러 스레드가 동시에 자원에 접근할 때 문제가 발생할 수 있습니다. 이를 해결하기 위해 '동기화(synchronization)'가 필요합니다.

    synchronized 키워드를 사용하여 메서드나 블록을 동기화 할 수 있습니다.

    public synchronized void synchronizedMethod() {
        // ...
    }
    
    public void anotherMethod() {
        synchronized(this) {
            // ...
        }
    }

     

    주요 메서드

    • sleep(): 스레드를 지정된 시간 동안 일시 중지.
    • join(): 한 스레드가 다른 스레드의 종료를 기다림.
    • yield(): 현재 스레드의 실행을 중지하고 다른 스레드에게 실행 기회를 제공.

     

     

    Java에서 스레드의 생명 주기 (Thread Life Cycle)

    Java에서의 스레드는 여러 상태를 거치며 생명 주기를 갖습니다. 스레드의 상태는 스레드가 생성되어 시작되고, 실행되며, 일시 중지되고, 재시작되고, 종료될 때까지의 과정을 나타냅니다. 스레드의 생명 주기를 이해하는 것은 스레드 동작과 동기화 문제를 더 잘 파악하는 데 도움이 됩니다.

     

    신규(New)

    • 스레드 객체가 생성되면, 스레드는 '신규' 상태에 있습니다.
    • Thread 클래스의 객체가 생성되었지만 start() 메서드가 아직 호출되지 않은 상태를 의미합니다.

     

    실행 가능(Runnable)

    • 스레드의 start() 메서드가 호출되면, 스레드는 '실행 가능' 상태로 전환됩니다.
    • 스레드가 현재 실행 중이거나, 실행을 기다리는 상태를 의미합니다. 실제로 CPU를 얻어서 실행되는지 아니면 실행을 위해 대기 중인지는 해당 상태에서 구분되지 않습니다.

     

    대기(Waiting)

    • 스레드가 다른 스레드의 작업을 기다리게 되면 '대기' 상태로 전환됩니다.
    • 예를 들어, wait(), join() 또는 LockSupport.park() 메서드에 의해 대기 상태로 들어갈 수 있습니다.

     

    타임 대기(Timed Waiting)

    • 스레드가 지정된 시간 동안 대기하게 되면 '타임 대기' 상태로 전환됩니다.
    • 예를 들어, sleep(), wait() with timeout, join() with timeout 또는 LockSupport.parkNanos(), LockSupport.parkUntil()과 같은 메서드에 의해 타임 대기 상태로 들어갈 수 있습니다.

     

    차단(Blocked)

    • 스레드가 잠긴 락(lock)의 해제를 기다리는 상태입니다.
    • 스레드가 synchronized 블록에 들어가려고 할 때 이미 다른 스레드에 의해 락이 획득된 경우, 해당 락이 해제될 때까지 '차단' 상태로 남게 됩니다.

     

    종료(Terminated)

    • 스레드의 작업이 완료되거나, 예외로 인해 중단된 경우 '종료' 상태가 됩니다.
    • 스레드가 정상적으로 실행을 마쳤거나 중간에 예외가 발생하여 종료되는 경우를 모두 포함합니다.

     

     

    댓글