싱글 스레드와 멀티 스레드
- 싱글 코어일 때에는 멀티 스레드라도 하나의 코어가 번갈아가면서 작업을 수행하기 때문에 두 작업이 겹치지 않는다
- 멀티 코어인 경우에는 멀티 스레드로 작업을 하는 경우 동시에 두 스레드가 수행될 수 있어서 실행이 겹치는 부분이 발생한다
- 자원을 두고 두 스레드가 경쟁을 하게 된다
- 여러 스레드가 여러 작업을 동시에 진행하는 것을 병행이라 하고 하나의 작업을 여러 스레드가 나눠서 처리하는 것을 병렬이라고 한다
- OS의 프로세스 스케줄러에 의해 시행순서와 실행시간이 결정되기 때문에 실행 결과는 매번 달라질 수 있다
- 자바가 OS 독립적이라고 하지만 실제로 몇가지는 OS 종속적인 부분이 몇 가지 있는데 스레드도 그 중의 하나이다
- 두 스레드가 서로 다른 자원을 사용하는 작업의 경우에는 멀티 스레드 프로세스가 더 효율적이다
스레드의 우선 순위
- 스레드는 우선 순위라는 속성(멤버 변수)을 가지고 있는데 이 우선 순위의 값에 따라 스레드가 얻는 실행 시간이 달라진다
- 스레드가 수행하는 작업의 중요도에 따라 스레드의 우선 순위를 서로 다르게 지정하여 특정 스레드가 더 많은 작업 시간을 갖도록 할 수 있다
- 멀티 코어에서는 스레드의 우선 순위에 따른 차이가 거의 없다
- OS마다 다른 방식으로 스케줄링 하기 때문에 어떤 OS에서 실행하느냐에 따라 다른 결과를 얻을 수 있다
- 자바는 스레드가 우선 순위에 따라 어떻게 다르게 처리되어야 하는지에 대해 강제하지 않으므로 스레드의 우선 순위와 관련된 구현이 JVM마다 다를 수 있기 때문이다
- 차라리 스레드에 우선 순위를 부여하는 대신 작업에 우선 순위를 두는 편이 나을 수 있다
스레드 그룹
- 보안상의 이유로 도입된 개념
- 자신이 속한 스레드 그룹이나 하위 스레드 그룹은 변경할 수 있지만 다른 스레드 그룹의 스레드는 변경할 수 없다
- 모든 스레드는 반드시 스레드 그룹ㄹ에 포함되어 있어야 한다
- 스레드 그룹을 지정하는 생성자를 사용하지 않은 스레드는 기본적으로 자신을 생성한 스레드와 같은 스레드 그룹에 속하게 된다
- 자바 어플리케이션이 실행되면 JVM은 main과 system이라는 스레드 그룹을 만들고 JVM 운영에 필요한 스레드들을 생성해서 스레드 그룹에 포함시킨다
- ex: main이라는 이름의 스레드는 main스레드 그룹에 속하고 가비지 컬렉션을 수행하는 Finalizer 스레드는 system 스레드 그룹에 속한다
데몬 스레드
- 데몬 스레드는 다른 일반 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드
- 일반 스레드가 모두 종료되면 데몬 스레드는 강제적으로 자동 종료된다
- 보조 역할을 수행하기 때문에 존재 의미가 없어짐
- 데몬 스레드의 예로는 가비지 컬렉터, 워드 프로세서의 자동 저장, 화면 자동 갱신 등이 있다
- 데몬 스레드는 무한 루프와 조건문을 이용해서 실행 후 대기하고 있다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다
- 데몬 스레득다 생성한 스레드는 자동적으로 데몬 스레드가 된다
스레드의 실행제어
- 스레드의 상태
- new : 스레드가 생성되고 아직 start()가 호출되지 않은 상태
- runnable : 실행 중 또는 실행 가능한 상태
- blocked : 동기화 블럭에 의해서 일시정지된 상태(lock이 풀릴 때까지 기다리는 상태)
- waiting, timed_waiting : 스레드의 작업이 종료되지는 않았지만 실행 가능하지 않은 일시 정지 상태. timed_waiting은 일시정지시간이 지정된 경우
- terminated : 스레드의 작업이 종료된 상태
- 스레드의 생성부터 소멸
- 스레드를 생성하고 start()를 호출하면 바로 실행되는 것이 아니라 실행대기열에 저장되어 자신의 차례가 될 때까지 기다려야 한다
- 실행 대기열은 큐와 같은 구조로 먼저 실행 대기열에 들어온 스레드가 먼저 실행된다
- 실행대기상태에 있다가 자신의 차례가 되면 실행 상태가 된다
- 주어진 실행시간이 다되거나 yield()를 만나면 다시 실행대기상태가 되고 다음 차례의 스레드가 실행상태가 된다
- 실행 중에 suspend(), sleep(), wait(), join(), I/O Block에 의해 일시정지상태가 될 수 있다
- 지정된 일시정지 시간이 다 되거나 notify(), resume(), interrupt()가 호출되면 일시정지상태를 벗어나 다시 실행대기열에 저장되어 자신의 차례를 기다린다
- 실행을 모두 마치거나 stop()이 호출되면 스레드는 소멸된다
- 일시정지 상태가 된 스레드는 지정된 시간이 다 되거나 interrupt()가 호출되면 interruptedException이 발생하기 때문에 try~catch문으로 예외 처리를 해줘야 한다