프로세스는 운영체제에서 할당받은 메모리를 가지고 실행합니다.
스레드는 프로세스안에서 작업을 실행하는 역할을 가지고 있습니다.
멀티프로세스 개념은 여러개의 프로세스를 가지고 있지만 서로 연관이 안되어있어서 프로세스에 에러가 발생해도 다른 프로세스는 문제 없이 작동합니다. Ex. 워드를 사용하다 오류때문에 종료를 해야되지만 엑셀은 지속적으로 사용가능한 상황.
반면 멀티스레드는 하나의 프로세스안에서 실행이되기 때문에 만약 하나의 스레드에 문제가 발생하면 다른 스레드에도 영향을 끼칩니다. Ex. 메신저어플에서 파일을 보내다가 문제가 생기면 메신저 통채로 종료되는 현상.
어떤 자바 애플리케이션이건 메인 스레드는 반드시 존재한다. 자바에서는 작업 스레드도 객체로 생성된다. Java.lang.Thread를 직접 객체화해도 되고 또는 상속해서 하위클래스를 사용해도 된다.
1. Implement Runnable
2. Extends Thread
Thread는 Runnable 매개값으로 받아야한다. 그래서 실행할 클래스에서 상속해서 대입할 수 있고 또는 익명객체형식으로 바로 구현이 가능하다. Runnable은 함수적 인터페이스여서 람다식방식도 가능하다.
구현을 하고나서 스레드를 실행시킬려면 .start()메소드를 사용해야 실행이된다.
Thread는 기본적으로 자기이름 + n번호를 가지고 있다. setName통해서 이름은 재정의가 가능하다.
멀티스레드는 동시성(Concurrency) 또는 병렬성(Parallelism)으로 실행된다.
동시성은 하나의 코어에서 멀티 스레드가 번갈아가면서 실행하고 병렬성은 멀티 코어에서 개별 스레드를 실행한다. 싱글 cpu는병렬적으로 실행이되는 것 처럼 보이지만 빠른 동시성을 실행하는 것이다.
스레드를 어떤 순서로 실행할지 정하는 것이 스레드 스케줄링이라고 한다.
스케줄링은 우선순위(priority)방식 그리고 순환 할당(round robin)방식을 사용한다.
우선순위 방식은 우선순위가 높은 스레드를 실행 상태를 더 많이 가지게 하는 방식이다.
순환 할당은 시간 할당량(time slice!)을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식이다.
Priority 방식은 코드로 제어할 수 있지만 round robin 순환 할당 방식은 jvm에서 정해지기 때문에 코드로 제어할 수 없다.
우선순위느 1~10, 1이 제일 낮고 10이 가장 높다. 기본 순위는 5로 할당이된다.
setPriority로 우선순위를 정할 수 있고, 가독성을 높이기 위해 상수를 사용해도 좋다.
쿼드 코어일 경우에는 4개의 스레드가 병렬성으로 실행이 되기 때문에 우선순위 방식이 크게 영향을 미치지 못한다. (현재 사용하는 노트북은 intel i7 9th gen, 8개의 코어를 가지고 있으니 8개의 스레드까지 병렬성으로 처리 가능하네)
싱글 스레드 프로그램에서는 객체를 독차지해도 되지만 멀티 스레드에서는 공유 객체를 사용하면 하나의 스레드에서 변경을 하면 다른 스레드에서 원하는 결과값이 안나올 수 도 있다.
멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역을 임계 영역(critical section)이라고 한다. 자바에서 임계 영역을 지정하기 위해 동기화(synchronized)를 사용한다. 스레드가 동기화 메소드 및 블록을 사용하면 잠금을 걸어 다른 스레드가 임계 영역 코드를 실행 못하게 한다.
스레드는 바로 실행되는게 아니라 실행대기 상태에서 스케줄링을 기달린다.
New = 스레드 객체가 생성직전
Runnable = 언제든지 실행 가능한 상태
Waiting = 다른 스레드가 통지할 때까지 기다리는 상태
Timed_waiting = 주어진 시간 동안 기다리는 상태
Blocked = 사용하고자 하는 객체의 락이 풀릴 때까지 기다리는 상태
Terminated = 실행을 마친 상태
Sleep()은 일시정지, interrupt()메소드가 호출되며 interruptedException이 발생해서 예외 처리가 필요하다.
Yield()은 다른 스레드한테 양보하는 메소드
Join()은 다른 스레드 종료를 기다리는 메소드
Wait()는 일시정지가 된다. 자기 스스로 실행대기로 못간다. 그래서 notify, notifyall를 사용하면 일시정지가 풀린다.
두 개의 스레드가 교대로 번갈아 가며 실행해야할 경우에 주로 사용한다.
동기화 블록 메소드에서만 호출 가능한 object메소드입니다!
스레드를 종료시킬때 stop를사용하면 자원들이 불안전한 상태로 남겨진다. 그래서 stop 플레그를 사용, while문을 통한 boolean를 사용하자. 하지만 이렇게 하면 일시정지한 스레드는 종료를 못한다. Interrupt()는 일시정지 상태에만! interruptedException이 발생해서 스레드를 종료시킨다. 즉 만약 실행상태일 경우에는 interruptedException이 발생하지 않아서 스레드를 종료를 못시킨다.
주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드가 데몬 스레드
Ex. 위드프로세서의 자동저장, 워드가 실행이 아닌 상태에서는 자동저장 스레드의 존재가 필요가 없다.
스레드그룹을 사용해서 스레드끼리 묶을수 있다. 스레드 그룹의 제일 큰 역할은 interrupt인데, interrupt를 한 그룹에 사용하면 모든 스레드는 정지가 된다.
스레드풀- 스레드가 많이 생성되면 cpu에 저하가 생겨서 이런 현상을 방지하기위해 미리 스레드풀이란걸 만든다. 스레드를 제한된 개수만큼 생성. 작업 큐에 들어오는 작업들을 하나씩 스레드가 맏아 처리한다.
스레드풀 = executeservice
Runnable은 작업 처리후 리턴 값이 없고, callable은 작업 처리후 리턴 값이 있다.
스레드풀에 작업처리 요청을 하기 위해선 runnable/callable로 실행을 시켜줘야한다.
executorService는 작업 큐에있는 객체들을 처리하기 위해 두가지 메소드를 실행할 수 있다, execute 그리고 submit.
Execute는 스레드가 종료되고 해당 스레드는 제거된다. 작업 처리를 위해 새로운 스레드를 생성한다.
Submit은 스레드가 종료되지 않고 다음 작업을 위해 재사용된다.
'IT > ETC' 카테고리의 다른 글
The Shawshank Redemption review (4) | 2019.12.16 |
---|---|
이것이 자바다 노트3(제너릭) (1) | 2019.12.14 |
이것이 자바다 노트1 (0) | 2019.12.09 |
Garbage Collector (0) | 2019.12.01 |
Comparable vs Comparator (0) | 2019.12.01 |