Adventure Time - Finn 3
본문 바로가기

스레드

by hyun9_9 2024. 1. 18.

프로세스와 스레드

동시에 두 가지 이상의 작업을 처리하는 것을 멀티태스킹이라고 합니다 

컴퓨터에는 멀티대트킹을 위한 두 가지 도구가 있습니다 프로세스와 스레드 입니다

프로그램은 파일이 존재하지만 아직 메모리에 올라가있지 않은 상태 즉 실행되지 않은 코드의 집합을 말합니다 프로그램을 시행하는 순간 메모리에 올라가고 동작하게 되는데 이 상태의 프로그램을 프로세스라고 합니다

 

프로그램이 실행되면 메모리에 적재되고 프로세스가 됩니다 프로세스는 독립적으로 메모리에 등록되므로 여러 개의 프로그램을 동시에 실행할 수 있게 됩니다

이러한 프로세스 내부에 존재하면서 실행 흐름을 나타내는 것을 스레드라고 합니다 위에서 언급한 바와 같이 각각의 프로세스들은 메모리에 독립적으로 등록되어 서로 간섭할 수 없습니다

 

하나의 프로세스안에서 다양한 작업을 동시에 하기 위해 스레드가 각자 독립적으로 존재하여 일을 수행하게 됩니다 하나의 프로세스는 적어도 한 개의 스레드를 지니게 됩니다 

 

프로그램 :프로그래밍 코드의 집합체를 의미합니다

프로세스 : 프로그램의 한단위를 말 하며 실행 중인 프로그램으로 메모리에 독립적으로 저장되어 실행됩니다

스레드 : 프로그램 내에 동작하는 작업 단위를 말하며 스레드를 통해 동시에 여러 가지 작업을 할 수 있습니다

 


스레드의 사용

자바에서 스레드를 생성하는 방법

Thread클래스를 상속하여 run()메서드 구현

Runnable 인터페이스 구현

스레드는 클래스에 Thread를 상속받은 다음 Thread가 가지고 있는 run()메서드를 사용해 생성합니다 만약 클래스 상속이 어려운 경우에는Runnable인터페이스를 상속해 구현할 수 있습니다

 

1. Thread클래스 상속

스레드는 run() 메서드에서 구현하지만 클래스를 실행하기 위해서는 start() 메서드를 호출해야 합니다

 

2. Runnable 인터페이스 상속

자바는 다중 상속이 불가능하다는 것을 우리는 알고 있습니다 그렇다면 기존에 상속되어 있는 클래스를 스레드로 만들려면 Runnable 인터페이스를 상속하여 구현 할 수 있습니다 Thread클래스를 사용하는 것이 아닌 Runnable인터페이스를 구현하는 것입니다 다음과 같이 Runnable을 매개 값으로 갖는 생성자를 호출해 생성합니다

Thread th=new Thread(Runnable을 상속한 인스턴스);

Thread클래스를 선언하면서 Runnable을 상속한 클래스를 선언하여 매개변수로 넘겨 줘야합니다 그 이유는 실제 Thread클래스가 스레드를 실행하는 주체이고 Runnable 인터페이스를 상속한 클래스는 실행 코드를 지닌 객체이기 때문입니다

 

Runnable로 구현된 스레드를 실행하는 방법은 클래스를 상속할 때와 조금 다릅니다

메인클래스에서 스레드 선언 시 생성자 매개변수로 실행할 Runnable클래스를 넘겨 주어야 합니다 실제로 Runnable을 상속한 클래스는 Thread 클래스 내부에서 start()메서드를 실행할 때 수행하게 됩니다

 

3. 익명 클래스를 람다식으로 표현

이넡페이스를 익명객체로 선언하여 처리하면 따로 클래스를 만들지 않고도 스레드를 구현할 수 있습니다

 

4. Thread에 이름 부여하기

현재 진행중인 스레드가 어떤 작업을 하는지 알기 위해서 이름을 부여할 수 있습니다

우리가 생성한 스레드는 Thread-n 이라는 이름으로 자동 설정되는데 다른 이름으로 설정하고 싶다면 Thread클래스의 setName() 에서드를 변경합니다

 

Thread클래스 상속

public class MyTask extends Thread{

    public MyTask(){

        setName("myTask-1");

    }

}

Thread 클래스를 상속할 경우 상위 클래스 Thread가 가진 setter 메서드인 setName(String name);을 사용하여 이름을 지정할 수 있습니다

 

Runnable 인터페이스 상속

Runnable task =()->{

 

};

 

Thread myThread= new Thread(task);

myThead.setName("Thread-blue");

Runnable 인터페이스를 상속한 경우에는 Thread를 선언한 후 이름을 부여할 수 있습니다

 

5 멀티 스레드

여러 개의 스레드를 이용해 동시에 작업을 수행할 수 잇는데 이것이 바로 우리가 앞에서 설명한 멀티 스레드입니다 같은 시간에 서로 다른 독립적인 스레드가 일을 처리하는 것을 우리는 비동기 작업이라고 합니다

 


스레드 동기화

멀티 스레드 프로그램이 실행될 때 다수의 스레드가 하나의 데이터를 공유하면서 스레드 간의 경쟁이 일어날 수있습니다

경쟁이 정상적으로 이루어진다면 별문제가 없겠지만 간혹 스레드 사이에서 자원 소유의 순서가 잘못되어 예상치 못한 결과가 나타나게 됩니다

 

오류를 방지하기 위해 여러 스레드가 하나의 공유 데이터에 동시에 접근하지 못하도록 스레드의 실행을 제어하는데 이를 스레드 동기화라고 합니다

 

1 스레드 동기화 처리

멀티 스레드 프로그램에서 단 하나의 스레드만 처리할 수 잇는 영역을 임계 영역이라고 합니다 하나의 스레드가 이 영역에 진입할 때 락을 걸어 다른 스레드가 수행되지 못하도록 하고 작업이 종료되면 락을 풀어서 다른 스레드가 작업하도록 하는 것을 동기화 처리라고 합니다 이러한 동기화 처리를 하는 방법은 매우 간단합니다 블록 또는 메서드 단위로 처리할 수있는데 synchronized키워드를 함께 사용합니다

 

메서드 이름 앞에 synchronized 키워드를 사용하면 해당 메서드 전체를 동기화 처리할 수 있습니다

public synchronized void add()...

 

블록 동기화 처리

전체 메서드가 아닌 특정 영역만 동기화 처리를 할 수 있는데 이를 블록 동기화 처리라고 합니다 즉 블록 동기화 처리는 실제 실행하는 스레드의 일부분을 동기화하여 처리하는 방법을 말합니다

[블록 동기화]

synchronized (객체명)...

synchronized키워드를 사용해 현재 공유 중인 객체를 소괄호() 안에 명시하면 해당 자원에 대한 동기화가 진행됩니다

블록 동기화를 통해서 특정 실행 대상을 동기화하면 결과는 메서드 동기화와 동일하게 나타납니다 이렇듯 동기화 처리를 통해 다중 스레등의 작업 순서를 제어함으로써 원하는 경과를 효율적으로 얻을 수 있습니다

 


스레드 상태

스레드는 생성하고 실행 종료되기까지 다양한 상태를 가집니다. 각 스레드의 상태는 스레드 클래스에 정의되어 있으며 Thread.State 타입으로 알 수 있습니다

상태 상수 설명
생성 NEW 스레드 객체가 생성되었지만 아직 start() 메소두거 호출되지 않은 상태
대기 RUNNABLE 실행 대기 또는 실행 상태로 언제든지 갈 수 있는 상태
일시정지 WATING 다른 스레드가 종료될 때까지 대기하는 상태
TIMED_WATING 주어진 시간 동안 대기하는 상태
BLOCKED 락이 풀릴 때까지 대기하는 상태
종료 TERMINATED 수행을 종료한 상태

 

스레드 객체를 생성하고 START()메서드를 호출하면 바로 스레드가 실행되는 것처럼 보이지만 사실은 실행 대기 상태가 됩니다 싱행되지 않고 기다리고 있다가 하나의 스레드가 선택되면 CPU가 run() 메서드를 실행하도록합니다 이때 실제 싱행 상태가 되며 실행 상태의 스레드는 run()메서드를 모두 실행하기 전에 다시 실행 대기 상태로 돌아갈 수 있습니다 다시 대기 상태가 되고 실행 상태가 되기를 반복하면서 조금씩 코드를 수행합니다 더 이상 실행할 코드가 없으면 실행을 멈추게 되는데 이 상태를 종료 상태라고 합니다

 

1 NEW 와 RUNNABLE, TERMINATED

처음 스레드가 생성ㄷ괴면 스레드는 NEW 상태가 됩니다 생성이후에 start() 메서드를 실행하면 스레드는 RUNNABLE 상태로 변하고 시작이후에 스레드가 종료되면 TERMINATED상태가 됩니다

 

2 스레드 WAIT

스레드 WAIT 상태는 필요에 의해서 스레드를 잠시 멈춤 상태로 두는 것을 의미합니다 스레드를 잠시 멈춤상태로 만들때는 일정 시간을 지정하거나 멈춤 상태의 락이 풀릴 때까지 대기하도록 만들 수 있습니다

 

sleep

sleep(int mils)메서드는 주어진 시간동안 스레드를 정지시키는 메서드입니다 해당 기능은 모든 스레드를 대기시키며 주어진 시간이 지나면 풀리게 됩니다 

 

wait()와 notify()

여러 개의 스레드가 동시에 동작하다 보면 하나의 스레드가 완료되어야 다음 스레드가 동작할 수 있는 경우가 있습니다 

wait()메서드는 스레드를 대기시키고 notify()메서드는 대기 중인 스레드를 다시 동작시킬 때 사용합니다

 

 

 

 

'' 카테고리의 다른 글

파일 입출력  (0) 2024.01.20
람다식  (0) 2024.01.15
기본 API 클래스  (1) 2024.01.11
예외처리  (0) 2024.01.06
내부 클래스  (1) 2024.01.06