멀티 스레드 개념
프로세스
- 사용자가 애플리케이션을 실행하면 운영체제로 부터 실행에 필요한 메모리를 할당받아 애플리케이션의 코드를 실행하는데 이것이 프로세스라고 부른다.
멀티 태스킹
- 두 가지 이상의 작업을 동시에 처리하는 것을 말하는데, 운영체제는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행하는 것을 멀티 태스킹이라 한다.
멀티 프로세스와 멀티 스레드
- 멀티 프로세스의 경우 운영체제에서 할당받은 자신의 메모리를 가지고 실행하기 때문에 서로 독립적이기 때문에 하나의 프로세스에서 오류가 발생해도 다른 프로세스에는 영향을 주지않는다.
- 멀티 스레드의 경우 한 프로세스 내에서 생성되기 때문에 스레드가 예외를 발생할경우 프로세스가 종료되어 다른 스레드에게 영향을 미칠수있다.
동시성 , 병렬성
- 동시성 : 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질로, 번갈아 가는 속도가 빨라 병렬처럼 보인다.
- 병렬성 : 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 것을 말한다.
스레드 우선순위
- 우선순위 방식 : 우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링하는 것을 말한다.
- 순환 할당 방식 : 시간 할당량을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식을 말한다.
동기화 메소드와 동기화 블록
- 멀티 스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 하는 경우가 있다. 동시 작업 할경우 의도한 결과와 다르게 동작할 수 있다.
- 스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없도록 하려면 스레드 작업이 끝날 때까지 객체에 잠금을 걸어서 다른 스레드가 사용할 수 없도록 해야 한다.
- 단 하나의 스레드만 실행할 수 있는 코드 영역을 임계 영역 (critical section)이라고 한다.
- java는 임계 영역을 지정하기 위해 동기화(synchronized) 메소드와 동기화 블록을 제공한다. 하지만 synchronized는 순서를 보장하지 않는다.
스레드의 상태
상태 | 열거 상수 | 설명 |
---|---|---|
객체 생성 | NEW | 스레드 객체가 생성, 아직 start() 메서드가 호출되지 않은 상태 |
실행 대기 | RUNNABLE | 실행 상태로 언제든지 갈 수 있는 상태 |
일시정지 | WAITING | 다른 스레드가 통지할 때까지 기다리는 상태 |
일시정지 | TIME_WAITING | 주어진 시간 동안 기다리는 상태 |
일시정지 | BLOCKED | 사용하고자 하는 객체의 락이 풀릴 때까지 기다리는 상태 |
종료 | TERMINATED | 실행을 마친 상태 |
- yield() : 실행 중에 우선순위가 동일한 다른 스레드에게 실행을 양보하고 실행 대기 상태가 된다.
- notify() : 동기화 블록 내에서 wait() 메소드에 의해 일시 정지 상태에 있는 스레드를 실행 대기 상태로 만든다.
- join() : join()메서드를 호출한 스레드는 일시 정지 상태가 된다. join() 메서드를 맴버로 가지는 스레드가 종료되거나 매개값으로 주어진 시간이 지나야 한다.
데몬 스레드
- 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다. 주 스레드가 종료되면 데몬 스레드는 강제적으로 자동 종료되는데, 그 이유는 주 스레드의 보조 역할을 수행하므로 주 스레드가 종료되면 데몬스레드의 존재가 의미가 없어지기 때문이다.
스레드풀
- 스레드 개수가 증가되고 그에 따른 스레드 생성과 스케줄링으로 인해 CPU가 바빠져 성능저하가 오게되는데, 갑작스러운 병렬 작업의 폭증으로 인한 스레드의 폭증을 막으려면 스레드풀을 사용해야 한다.
- 스레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다.
- 작업이 끝나면 다시 작업 큐에서 새로운 작업을 가지고 와서 처리를 한다.
스레드풀 생성
- ExecutorService 구현 객체는 Executors 클래스의 다음 두 가지 메서드 중 하나를 이용해서 간편하게 생성할 수 있다.
1
ExcutorService excutorService = Excutors.newCachedThreadPool();
1
2
3
ExcutorService excutorService = Excutors.newFixedThreadPool(
Runtime.getRuntime().availavleProcessors();
)