티스토리 뷰

Java

멀티스레드

lkh's 2018. 10. 27. 01:35

1. 프로세스와 스레드

프로세스는 실행중인 하나의 애플리케이션으로서 운영체제로부터 실행에 필요한 메모리 공간을 할당받는다. 

스레드는 프로세스 내에서의 작업의 실행 흐름이다. 

멀티 프로세스는 애플리케이션 단위의 멀티태스킹이고, 멀티스레드는 애플리케이션 내부에서의 멀티테스팅이라고 정의할 수 있다.

프로세스는 운영체제로부터 할당받은 메모리를 가지고 실행하기 때문에 각각 독립적이다. 하지만, 스레드는 하나의 메모리 공간을

공유하기 때문에 하나의 스레드에서 예외가 발생할 경우, 전체 프로세스가 종료될 수 있다. 

자바에서 main 메소드는 자바의 main 스레드에 의해 실행이 된다. 이 메인 스레드가 종료될지라도, 다른 멀티스레드들이 종료되지 않는다면

프로세스는 종료되지 않는다.


2. 스레드 우선순위

멀티스레드는 동시성과 병렬성으로 실행되기 때문에 용어에 대한 구분이 필요하다.

동시성은 멀티테스킹을 위해 하나의 코어에서 여러 스레드들이 번갈아가며 실행되는 성질을 의미한다. 싱글코어에서의 멀티작업은 병렬적으로 

실행되는 것이 아니라, 빠른 속도로 번갈아 가며 실행되기 때문에 병렬적으로 실행되는 것처럼 느끼는 것 뿐이다. 병렬성은 멀티코어에서 

각각 스레드가 동시에 실행되는 것을 의미한다. 


스레드의 갯수가 코어의 갯수보다 많을 경우, 스레드를 어떤 순서에 맞게 실행을 할 것인 결정이 필요한데, 이것을 스케줄링이라고 부른다.

스레드의 스케줄링은 우선순위(Priority) 방식과 순환할당(Round-Robin) 방식을 사용한다. 우선순위 방식은 우선순위가 높은 스레드를 더 많이

실행할 수 있도록 설계하는 것으로, 개발자가 각 스레드의 우선순위를 제어할 수 있다. 반면, 순환할당 방식은 시간할당량(Time Slice)을 정해서

각 스레드들을 시간할당량만큼 동등하게 실행한다. JVM에 의해 실행이 되기 때문에 개발자가 제어할 수 없다. 


3. 동기화 메소드와 공유블록

멀티 스레드에서는 각가의 스레드가 하나의 객체를 공유해서 사용할 경우, 연산 시, 원하는 값을 얻지 못하는 경우가 존재한다. 

이와 같은 문제를 해결하기 위해서는 스레드가 하나의 객체를 사용할 경우, 작업이 끝날 때까지 다른 스레드가 변경하지 못하도록 잠금을 걸 수 있다.

이처럼 멀티스레드 환경에서 단 하나의 스레드만 실행할 수 있는 코드 영역을 임계영역(Critical Section)이라고 부른다. synchronized 키워드를

이용하여 동기화 메소드를 생성할 수 있다. 동기화 메소드는 메소드 내용 전체가 임계영역이고, 메소드가 종료될때까지 객체에 대해 잠금을 걸 수 있다.

만약, 전체가 아닌, 특정 영역만 임계영역으로 설정하고 싶다면, 특정 synchronized 키워드를 이용해서 동기화 블록을 생성하면 된다.


4. 스레드 상태

 객체 생성

 NEW

 스레드가 객체가 생성되고, run() 메소드가 호출되지 않는 상태

 실행대기

 RUNNABLE

 스케줄링이 되지 않아서 실행을 기다리고 있는 상태

 스케줄링이 되면 CPU를 독점하고, run() 메소드를 실행 가능

 일시정지

 WAITING

 다른 스레드가 일시정지 상태일때까지 대기하는 상태

 

 TIME_WAITING

 주어진 시간동안 대기하는 상태

 

 BLOCKED

 사용하고자 하는 객체의 잠금이 풀릴때까지 대기하는 상태

 종료

 TERMINATED

 실행을 마친 상태


 interupt()

 일시 정지 상태의 스레드에서 InteruptedException 예외를 발생시켜서, 예외처리 코드에서 실행대기 상태로 가거나,

 종료상태로 갈 수 있도록 지원

 notify(), notifyAll()

 동기화 블록내에서 wait()메소드에 의해 일시정지 상태에 있는 스레드들을 실행대기 상태로 변경

 sleep(mills, ns)

 주어진 시간동안 스레드를 일시정지 상태로 만들고, 시간이 지나면 자동으로 실행대기 상태로 변경

 join(), join(mills, ns)

 스레드를 일시정지 상태로 변경. 실행대기 상태로 변경되기 위해서는 join() 메소드를 가지고 있는 스레드가 종료되거나,

 join의 매개변수로 주어진 시간이 지나면 자동으로 실행대기 상태로 변경가능

 wait(), wait(mills, ns)

 동기화 블록에서 스레드를 일시정지 상태로 변경. wait의 매개변수로 주어진 시간이 지나면 자동으로 실행대기 상태로 변경

 또는, notify(), notifyAll() 메소드를 통해 실행대기 상태로 변경 가능

 yield()

 실행중에 우선순위가 높은 스레드에게 CPU를 양보하고, 실행대기 상태로 본인은 변경 

 stop()

 스레드 종료 


5. 스레드폴

스레드폴은 작업 처리에 사용되는 스레드를 제한된 수만큼 정해 놓고, 작업큐에서 작업들을 가져와 스레드에서 처리한다. 스레드에서 작업이 끝나면

작업큐에서 다시 작업을 가져와 처리하는 것을 반복한다. 그렇기 때문에 작업량이 늘어도 스레드의 갯수가 한정적이기 때문에 스레드의 증가로 인한

애플리케이션의 성능 저하를 방지할 수 있다. 



공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함