본문 바로가기
기록하는 중/JAVA

[Java] 멀티 스레드

by 성장하는 요롱이 2024. 1. 20.
  스레드
  • 실행중인 하나의 애플리케이션을 프로세스라고 부름
  • Java 프로그램은 하나의 프로세스로 만들어져 실행됨
  • 지금까지는 프로세스에서 하나의 스레드가 생성되고 main() 메소드가 호출되어 실행됨(단일 스레드)
  • 스레드는 한 가지 작업을 실행하기 위해 순차적으로 실행할 코드를 실처럼 이어놓았다고 해서 유래된 이름
  • 스레드는 실행 중인 프로그램 내에 존재하는 소규모 실행 흐름(스레드가 2개면 2개의 코드 실행 흐름)
  • 스레드는 경량 프로세스

 

  멀티 스레드
  • 하나의 프로세스 내부에서 여러 스레드가 만들어져 동시 실행될 수 있음
  • Java 프로그램은 하나의 스레드(main 스레드)로 시작됨
  • main 스레드에서 자식 스레드를 만들어 시작시킬 수 잇음
  • 그러면 여러 스레드가 동시에 독립적으로 실행되고 종료됨

 

 Thread 클래스
  • 스레드의 생성과 관리를 위한 메소드를 제공
  • 스레드 생성을 위해 Thread 유형의 객체가 필요함 

 

  Thread 클래스의 생성자
// 객체를 생성하려면 Runnable을 매개값으로 갖는 생성자를 호출
// Runnable은 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라고 해서 붙여진 이름
// Runnable - 인터페이스 타입
Thread thread = new Thread(Runnable target);

// Runnable 안에 run() 메소드를 구현 클래스에서 재정의해서 작업 스레드가 실행할 코드를 작성해야함 
Class Task implements Runnable{
	public void run(){
    	스레드가 실행할 코드;
    }
}

// 매개 값으로 하는 Thread 생성자 호출
Thread thread = new Thread(task);

// 코드 절약
Thread thread = new Thread( new Runnable{
	public void run(){
    	스레드가 실행할 코드;
    }
});


// 메소드를 호출하여 run() 메소드 실행
thread.start();

 

  멀티 스레드의 실행
  • 멀티 스레드 프로그램 실행 결과는 예측할 수 없음 - 실행 결과가 매번 다를 수 있음
  • 각 스레드는 정해진 순서 없이 독립적으로 실행됨
  • main 스레드는 다른 스레드를 시작시키나 다른 스레드의 실행과 무관하게 실행되고 종료됨

 

  스레드의 상태
  • 보통 1개의 CPu를 사용하여 여러 스레드가 수행
  • CPU를 얻어 실행되고 최종적으로 종료될 때까지 여러 상태 변화를 겪음
상태 설명
Startable 객체가 생성되었으나 start()의 실행 전
Runnable start()메소드가 호출되었으나 CPU 획득 전
Running CPU를 얻어 실행 중
Not Running CPU를 잃고 중단된 상태
Blocked, Waiting, Timed_Waiting
Dead run()메소드가 종료된 상태

 

  스레드의 상태 제어를 위한 메소드
메소드 설명
void setPriority(int newPriority) 스레드의 우선순위를 변경.
높은 우선순위를 가지는 스레드가 CPU를 얻을 확률이 높음
static void sleep(long millis) throws InterruptedException 현재 실행 중인 스레드가 정해진 시간 동안 실행을 멈추고 Not Running 상태로 들어감
static void yield( ) 현재 실행중인 스레드가 잠시 실행을 멈추고 Runnable 상태로 들어감
CPU를 다른 스레드에게 양보하는 것
void join() throws InterruptedException 스레드가 종료될 때까지 기다림
현재 실행 중이던 스레드는 Not Running 상태로 들어감
void join(long millis)는 최대 millis 시간 동안 기다림
기다리는 중에 다른 스레드가 이 스레드를 깨워주면 InterruptedException을 받으면서 리턴됨
void interrupt() 스레드를 인터럽트시킴
스레드가 wait(), join(), sleep()에 의해 중단된 상태였으면 그 상태에서 깨어나 Runnable 상태가 됨
void wait() throws InterruptedException 객체를 처리 중인 스레드를 중지시킴
void wait(long millis) throws InterruptedException 객체를 처리 중인 스레드를 정해진 시간 동안 중지시킴
다른 스레드가 해당 객체에 대한 notify() 메소드를 실행시켜 주면 이 스레드가 깨어날 수 있음
이 메소드는 synchronized 메소드의 내부에서만 호출 가능
void notify() wait()를 호출하여 중단된 스레드를 깨워줌
이 메소드는 synchronized 메소드의 내부에서만 호출 가능

 

  스레드 동기화
  • 스레드 간의 간섭 - 여러 개의 스레드들이 하나의 공유 객체에 동시 접근하는 경우 일관성이 깨짐
  • 스레드 동기화 - 서로 다른 스레드들이 공유 자원을 다룰 때, 일관성을 유지하도록 하는 것
  • 한 번에 오직 한 개의 스레드만이 해당 공유 객체에 접근하도록 동기화 함
  • 상호 배제 원칙
  • 키워드 synchronized - 동기화 메소드 또는 동기화 블록을 제공, 공유 자원을 수정할 때, 다른 스레드에서 같은 코드를 수행 할 수 없게 함

 

  synchronized 메소드
  • 한번에 하나의 스레드에 의해서만 실행 가능
  • synchronized 메소드를 실행하려면 메소드를 호출한 객체에 대한 lock을 얻어야 함
  • 다른 스레드는 동일 객체에 대해 synchronized 메소드를 실행할 수 없게 됨 
public synchronized void func(){...}
  • 일부 블록만 동기화 하는 것도 가능함 - 객체는 공유자원으로 대개 this
synchronized(객체){...}
class Counter {
	private int c = 0;
    public synchronized void increment( ){c++;}
    public synchronized void decrement( ){c--;}
    public int value( ) {return c;}
}

class Counter{
	private int c = 0;
    public void increment( ){
    	synchronized(this) { c++; }
    }
    public void decrement( ){
    	synchronized(this) { c--; }
    }
    public int value( ){return c;}
}

 

 

 

'기록하는 중 > JAVA' 카테고리의 다른 글

[Java] GUI 컴포넌트 - AWT  (0) 2024.01.22
[Java] AWT  (0) 2024.01.20
[Java] Map 컬렉션  (0) 2024.01.17
[Java] List 컬렉션  (0) 2024.01.12
[Java] Set 컬렉션 - JCF  (0) 2024.01.11