21.7.31
Chap 12. 스레드
1. 멀티 스레드
- 운영체제에서는 실행중인 하나의 애플리케이션을 프로세스라고 부른다.
- 하나의 애플리케이션은 멀티 프로세스를 만들기도 한다.
1) 스레드
-
운영체제는 두 가지 이상의 작업을 동시에 처리하는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킨다.
- 워드로 문서 작업하면서 노래 듣기
-
멀티 태스킹은 꼭 멀티 프로세스를 뜻하는 것은 아니다. 한 프로세스 내에서 멀티 태스킹을 할 수 있도록 만들어 진 애플리케이션이 존재한다.(멀티 스레드)
- 동영상 재생과 음악 재생 작업을 동시에 처리하는 미디어 플레이어
-
스레드는 하나의 코드 실행 흐름이다.
-
한 프로세스 내에 스레드가 2개라면 2개의 코드 실행 흐름이 생긴다는 의미이다. 이를 멀티 스레드라고 한다.
-
멀티 프로세스는 각 프로세스마다 서로 독립적이기 때문에 하나의 프로세스에서 오류가 발생해도 다른 프로세스에 영향을 미치지 않는다.
-
멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를 발생시키면 다른 스레드에 영향을 미친다.
-
때문에 멀티 스레드에서는 예외처리에 만전을 기해야한다.
2) 메인 스레드
-
모든 애플리케이션은 메인 스레드가 main() 메소드를 실행하면서 시작한다.
-
main() 메소드의 마지막 코드를 실행하거나 return문을 만나면 실행이 종료된다.
-
메인 스레드는 필요에 따라 작업 스레드들을 만들어서 병렬로 코드를 실행할 수 있다. 즉, 멀티 스레드를 생성해서 멀티 태스킹을 수행할 수 있다.
-
싱글 스레드 어플리케이션은 메인 스레드가 종료하면 프로세스도 종료된다.
-
멀티 스레드 어플리케이션은 메인 스레드가 작업 스레드보다 먼저 종료되더라도 작업 스레드가 실행중이라면 프로세스는 종료되지 않는다.
3) 작업 스레드 생성과 실행
- 메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성한다.
- 자바에서는 작업 스레드도 객체로 생성되기 때문에 클래스가 필요하다.
(1) Thread 클래스로부터 직접 생성하는 방법
- 다음과 같이 Runnable을 매개값으로 갖는 생성자를 호출해야한다.
Thread thread = new Thread(Runnable target);
- Runnable을 인터페이스 타입이기 때문에 구현 객체를 만들어 대입해야한다.
- run() 메소드를 재정의해야한다.
- Runnable 구현 객체를 생성한 후, 이것을 매개값으로 해서 Thread 생성자를 호출해야 작업 스레드가 생성된다.
Runnable task = new Task();
Thread thread = new Thread(task);
- 익명 객체로 코드를 짤 수 있다.
- 작업 스레드는 생성 즉시 실행되는 것이 아니라, start() 메소드를 호출해야 실행된다.
(2) Thread 하위 클래스로부터 생성
- Thread 클래스를 상속한 후 run() 메소드를 재정의해서 스레드가 실행할 코드를 작성한다.
public class WorkerThread extends Thread {
@Override
public void run() {
// 스레드가 실행할 코드
}
}
Thread thread = new WorkerThread();
스레드 이름
- 스레드를 생성하면 자동적으로 Thread-n이라는 이름이 설정된다.
- setName() 메소드로 변경할 수 있다.
- getName() 메소드로 스레드 이름을 알 수 있다.
- 위의 두 메소드는 인스턴스 메소드이므로 스레드 객체의 참조가 필요하다. 스레드 객체의 참조를 가지고 있지 않다면, Thread 클래스의 정적 메소드인 currentThread()를 이용해서 현재 스레드의 참조를 얻을 수 있다.
Thread thread = Thread.currentThread();
4) 동기화 메소드
- 멀티 스레드 프로그램에서 스레드들이 객체를 공유해서 작업하는 경우, 스레드 A가 사용하던 개체를 스레드 B가 상태를 변경할 수 있다.
- 이런 경우가 생기지 않게 메소드 선언에 synchronized 키워드를 붙이면, 한 스레드가 동기화 메소드가 선언된 객체를 사용하는 동안 다른 스레드가 해당 객체를 사용할 수 없다. 이때 또다른 스레드의 일반 메소드는 실행 가능하다.
2. 스레드 제어
1) 스레드 상태
운영체제는 두 가지 이상의 작업을 동시에 처리하는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당해주고, 병렬로 실행시킨다.
- 워드로 문서 작업하면서 노래 듣기
멀티 태스킹은 꼭 멀티 프로세스를 뜻하는 것은 아니다. 한 프로세스 내에서 멀티 태스킹을 할 수 있도록 만들어 진 애플리케이션이 존재한다.(멀티 스레드)
- 동영상 재생과 음악 재생 작업을 동시에 처리하는 미디어 플레이어
스레드는 하나의 코드 실행 흐름이다.
한 프로세스 내에 스레드가 2개라면 2개의 코드 실행 흐름이 생긴다는 의미이다. 이를 멀티 스레드라고 한다.
멀티 프로세스는 각 프로세스마다 서로 독립적이기 때문에 하나의 프로세스에서 오류가 발생해도 다른 프로세스에 영향을 미치지 않는다.
멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를 발생시키면 다른 스레드에 영향을 미친다.
때문에 멀티 스레드에서는 예외처리에 만전을 기해야한다.
모든 애플리케이션은 메인 스레드가 main() 메소드를 실행하면서 시작한다.
main() 메소드의 마지막 코드를 실행하거나 return문을 만나면 실행이 종료된다.
메인 스레드는 필요에 따라 작업 스레드들을 만들어서 병렬로 코드를 실행할 수 있다. 즉, 멀티 스레드를 생성해서 멀티 태스킹을 수행할 수 있다.
싱글 스레드 어플리케이션은 메인 스레드가 종료하면 프로세스도 종료된다.
멀티 스레드 어플리케이션은 메인 스레드가 작업 스레드보다 먼저 종료되더라도 작업 스레드가 실행중이라면 프로세스는 종료되지 않는다.
Thread thread = new Thread(Runnable target);
- run() 메소드를 재정의해야한다.
Runnable task = new Task();
Thread thread = new Thread(task);
public class WorkerThread extends Thread {
@Override
public void run() {
// 스레드가 실행할 코드
}
}
Thread thread = new WorkerThread();
Thread thread = Thread.currentThread();
- 스레드 객체를 생성하고 start() 메소드를 호출하면 바로 실행되는 것이 아니라 실행 대기상태가 된다.
- 실행 대기 상태란 언제든지 실행할 준비가 되어있는 상태를 말한다.
- 운영체제는 실행 대기 상태에 있는 스레드 중에서 하나를 선택해서 실행 상태로 만든다.
- 실행 상태의 스레드는 run() 메소드를 모두 실행하기 전에 다시 실행 대기상태로 돌아갈 수 있으며, 실행 대기 상태에 있는 다른 스레드가 선택되어 실행 상태가 되기도 한다.
- 실행 상태에서 run() 메소드의 내용이 모두 실행되면 스레드의 실행이 멈추고 종료상태가 된다.
2) 스레드 상태 제어
- 실행중인 스레드의 상태를 변경하는 것을 말한다.
주어진 시간동안 일시 정지
- Thread 클래스의 정적 메소드인 sleep()을 사용하면 실행 중인 스레드를 일정 시간 멈추게할 수 있다.
스레드의 안전한 종료
- stop()메소드가 제공되지만, 이 메소드를 사용하면 사용 중이던 자원이 불안정한 상태로 남겨지기 때문에 사용되지 않는다.
- stop() 플래그를 이용하는 방법
public class threadA extends Thread {
private boolean stop;
public void run() {
while( !stop ) {
// 스레드가 반복 실행하는 코드;
}
}
}
- interrupt() 메소드를 실행하는 방법
- interrupt() 메소드는 스레드가 일시 정지 상태에 있을 때 interruptedException을 발생시키는 역할을 한다. 이를 이용하면 run() 메소드를 정상 종료할 수 있다.
- interrup()를 호출한 후 정적메소드 interrupted()나 인스턴스 메소드 inInterrupted()를 활용하여 종료할 수도 있다.
3) 데몬 스레드
- 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다.
- 주 스데드가 종료되면 데몬 스레드는 강제적으로 자동 종료된다.
- start() 메소드 호출 전에 setDaemon(true)를 호출하면 된다.
- 현재 실행중인 메소드의 데몬스레드 여부는 isDaemon() 메소드를 사용하면 된다.
Author And Source
이 문제에 관하여(21.7.31), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@doforme/21.7.31저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)