혜야의 코딩스토리

[자바의 정석] 쓰레드 본문

꿈 : 멋진 개발자 🧸/자바의 정석

[자바의 정석] 쓰레드

hyeya_ 2022. 5. 23. 20:54

[쓰레드]

프로세스 == 자원+쓰레드

1개의 프로세스에 1개 이상의 쓰레드 필요

프로세스 : 쓰레드 = 공장 : 일꾼

-새로운 쓰레드를 생성하는 것이 새로운 프로세스 생성보다 비용대비 효율저

-장점: 효율적인 자원, 응답성 향상

-단점: 동기화 주의, 교착상태 발생위험(서로 대치), 기아 가능성O

 

*잘 동작하는 에러가 없는 코드가 좋은 코드다!!!!

 

[쓰레드의 구현과 실행]

1. Thread클래스를 상속

class MyThread extends Thread {

           public void run( ) { //Thread클래스의 run( )을 오버라이딩

           /* 작업내용 */

}

->

MyThread t1 = new MyThread( ); //쓰레드의 생성

t1.start( ); //쓰레드의 실행

 

2 .Runnable인터페이스를 구현

class MyThread2 implements Runnable {

           public void run( ) { //Runnable인터페이스의 추상메서드 run( )을 구현

           /* 작업내용 */

}

->

Runnable r = new MyThread2( );

Thread t2 = new Thread(r); //Thread(Runnable r)

t2.start( ); //쓰레드의 실행

 

[쓰레드의 실행 – start( )]

-쓰레드를 생성한 후에 start( )를 호출해야 쓰레드가 작업을 시작한다.

ThreadEx1_1 t1 = new ThreadEx1_1( ); //쓰레드 t1을 생성한다.

ThreadEx1_1 t2 = new ThreadEx1_1( ); //쓰레드 t2을 생성한다.

 

t1.start( ); //쓰레드 t1을 실행시킨다.

t2.start( ); //쓰레드 t2를 실행시킨다.

→ 쓰레드의 실행순서는 OS스케줄러에 의해 결정된다.(OS에 의존적)

 

[start( )run( )]

start( )는 새로운 call stack생성 (call stack2 : 서로 독립적인 작업 가능)

run( ) 하나의 호출 스택을 하나의 쓰레드가 실행

이해 안되면 호출스택 그림 그려보기

 

[main쓰레드]

-main메서드의 코드를 수행하는 쓰레드

-쓰레드는 사용자 쓰레드데몬 쓰레드’(보조 쓰레드) 두 종류가 있다.

*실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다.

 

[싱글쓰레드와 멀티쓰레드]

싱글쓰레드 : 순차적 작업

멀티쓰레드 : 동시에 작업 시작

[쓰레드의 I/O 블락킹(blocking)]

(Input / Output : 입출력)

*I/O블락킹 : 입출력시 작업 중단

 

[쓰레드의 우선순위(priority of thread)]

-작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있다.

void setPriority(int newPriority) //쓰레드의 우선순위를 지정한 값으로 변경한다.

int getPriority( ) //쓰레드의 우선순위를 반환한다.

public static final int MAX_PRIORITY = 10    //최대우선순위

MIN_PRIORITY = 1    //최소우선순위

NORM_PRIORITY = 5 //보통우선순위

 

[쓰레드 그룹]

-서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것

-모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함되어 있어야 한다.

-쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 ‘main쓰레드 그룹에 속한다.

-자신을 생성한 쓰레드(부모 쓰레드)의 그룹과 우선순위를 상속받는다.

 

[데몬 쓰레드]

-일반 쓰레드의 작업을 돕는 보조적인 역할을 수행.

-일반 쓰레드가 모두 종료되면 자동적으로 종료된다.

-가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용된다.

-무한루프와 조건문을 이용해서 실행 후 대기하다가 특정조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.

 

[쓰레드의 상태]

머릿속에 그림 그리면서 생각하기

[쓰레드의 실행제어]

-쓰레드의 실행을 제어할 수 있는 메서드가 제공된다.

이 들을 활용해서 보다 효율적인 프로그램을 작성할 수 있다.

static void sleep( ) : 지정된 시간(천분의 일초 단위)동안 쓰레드를 일시정지시킨다.

void join( ) : 다른 쓰레드 기다리기

void interrupt( ) : 깨우기

void suspend( ) : 일시정지

void resume( ) : 재개

static void yield( ) : 양보

→ static실행제어 메서드는 쓰레드 자기 자신에게만 호출 가능

 

*sleep( )

-현재 쓰레드를 지정된 시간동안 멈추게 한다.

-예외 처리를 해야 한다. (InterruptedException이 발생하면 깨어남)

-특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다.

 

*interrupt( ) : 대기상태(WAITING)인 쓰레드를 실행대기(RUNNABLE) 상태로 만든다.

*void interrupt( ) : 쓰레드의 interrupted상태를 false에서 true로 변경

*boolean isInterrupted( ) :쓰레드의 interrupted상태를 반환

*static Boolean interrupted( ) : 현재 쓰레드의 interrupted상태를 알려주고 false로 초기화

 

[쓰레드의 동기화 synchronization]

-한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것

-멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.

-진행중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 동기화가 필요

-동기화하려면 간섭 받지 않아야 하는 문장들을 임계 영역’(critical section)으로 설정

-임계영역은 락(lock)을 얻은 단 하나의 쓰레드만 출입가능(객체1개에 락1)

 

[synchronized를 이용한 동기화]

-synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지

1. 메서드 전체를 임계 영역으로 지정

2. 특정한 영역을 임계 영역으로 지정