열다섯번째날 [멀티 스레드 - 개념 / 작업 스레드 생성과 실행 / 스레드 우선순위]
목차
1. 멀티 스레드 개념
2. 작업 스레드 생성과 실행
3. 스레드 우선순위
멀티 스레드 개념
* 앱을 만들때 중요 / 웹을 만들땐 중요X
프로세스와 스레드
* 프로세스
- 운영체제에서 실행 중인 하나의 애플리케이션
- 사용자가 애플리케이션을 실행하면 운영체제로부터 실행에 필요한 메모리를 할당받아 애플리케이션의 코드를 실행하는 것
- 하나의 프로그램이 다중 프로세스를 만들기도 함 ex) Chrome 브라우저 두 개 실행 ➡️ 두개의 Chrome 프로세스 생성된 것
* 멀티태스킹
- 두 가지 이상의 작업을 동시에 처리하는 것
- OS는 멀티태스킹을 하도록 CPU, 메모리 자원을 프로세스마다 적절히 할당, 병렬로 실행시킴
* 스레드(thread)
- 사전적 의미 : 한 가닥의 실
- 한 가지 작업을 실행하기 위해 순차적으로 실행할 코드를 실처럼 이어 놓았다고 해서 유래된 이름
- 하나의 스레드는 하나의 코드 실행 흐름
* 멀티 프로세스 : 독립적으로 프로그램들을 실행하고 여러 가지 작업 처리. 애플리케이션 단위의 멀티 태스킹
* 멀티 스레드 : 한 개의 프로그램을 실행하고 내부적으로 여러 가지 작업 처리. 애플리케이션 내부의 멀티 태스킹
메인 스레드
- 모든 자바 프로그램은 메인 스레드가 main() 메소드 실행하며 시작
- main() 메소드의 첫 코드부터 아래로 순차적으로 실행
[실행 종료 조건]
마지막 코드 실행
return 문을 만나면
main 스레드는 작업 스레드들을 만들어 병렬로 코드들 실행
멀티 스레드 생성해 멀티 테스킹 수행
[프로세스의 종료]
싱글 스레드 : 메인 스레드가 종료하면 프로세스도 종료
멀티 스레드 : 실행 중인 스레드가 하나라도 있다면 종료되지 않음
작업 스레드 생성과 실행
* 멀티 스레드로 실행하는 어플리케이션 개발 : 몇 개의 작업을 병렬로 실행할지 결정하고 각 작업별로 스레드 생성
- 자바에서는 작업 스레드도 객체로 생성되기 때문에 클래스 필요함
* 작업 스레드 생성 방법
(1) java.lang.Thread 클래스로부터 직접 생성 : Runnable 인터페이스를 구현하는 클래스
(2) Thread 하위 클래스로부터 생성 : Thread 클래스 상속 후 run 메소드 재정의 해 스레드가 실행할 코드 작성
Thread 클래스로부터 직접 생성
* Runnable을 매개값으로 갖는 생성자를 호출해야 함 : Runnable은 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라는 의미
* Runnable은 인터페이스 타입 ➡️ 구현 객체를 만들어 대입해야 함
* Runnable에는 run() 메소드가 정의되어 있음 ➡️ 구현 클래스는 run()을 재정의해서 작업 스레드가 실행할 코드를 작성
Class Task implements Runnable{
public void run(){
스레드가 실행할 코드;
}
}
* Runnable은 작업 내용을 가지고 있는 객체일뿐, 실제 스레드X
* Runnable 구현 객체를 생성한 후, 이것을 매개값으로 해서 Thread 생성자를 호출해야 작업 스레드가 생성됨!
* 코드를 절약하기 위해 Thread 생성자를 호출할 때 Runnable 익명 객체를 매개값으로 사용할수도 있음 (이 방법이 더 많이 사용!!)
* Runnable 인터페이스는 run() 메소드 하나만 정의됨 : 함수적 인터페이스이기 때문에 람다식 매개값으로 사용 가능
//Thread 생성자 호출 방법
Runnable task = new Task();
Thread thread = new Thread(task);
//runnable을 익명객체로 사용 방법
Thread thread = new Thread(new Runnable(){
public void run(){
스레드가 실행할 코드;
}
} );
//람다식으로 사용 방법
Thread thread = new Thread(()->{
스레드가 실행할 코드;
} );
* 작업 스레드는 생성되는 즉시 실행되는 것X
* start() 메소드를 호출해야만 비로소 실행됨 : start() 메소드가 Runnable의 run() 메소드를 실행시킴
thread.start();
Thread 하위 클래스로부터 생성
* Thread 클래스를 상속한 후 run 메소드를 재정의해서 스레드가 실행할 코드를 작성하면 됨
public class WorkerThread extends Thread{
@Override
public void run(){
//스레드가 실행할 코드
}
}
Thread thread = new WorkerThread();
* Thread 익명 객체로 작업 스레드 객체 생성도 가능
Thread thread = new Thread(){
public void run(){
스레드가 실행할 코드;
}
};
스레드의 이름
* getName() 스레드 이름 알고 싶은 경우
thread.getName();
* setName() : 작업하는 스레드 이름 변경
* 스레드 이름을 설정하지 않은 경우 : "Thread - n"이라는 이름으로 설정. n은 스레드의 번호를 말함
thread.setName("스레드이름");
* currentThread() : 현재 동작하는 스레드의 참조를 얻기
Thread thread = Thread.currentThread();
* toolkit
그래픽 자원관련 시스템 정보 제공 합니다.
new 명령으로 만들수 없으며 Component의 Method인 getToolkit()이나 Toolkit.getDefaultToolkit을 사용해야 합니다.( Toolkit 객체가 하나만 존재해야 하므로…)
beep() : beep 음 출력
createimage(), getImage() : 이미지를 만들거나 Network 경로를 통해얻을 사용 합니다.
getPrintJob() : 프린터와 연결된 객체인 java.awt.PrintJob을 얻게 해 줍니다.
getScreenSoze() : 실제 화면의 크기를 구해주며 스플레쉬(Splash) 윈도우를 만들때 유용 합니다.
getScreenResolution() : 현재 화면이 인치당 몇 개의 점이 들어가는 해상도인지 알려줌.
getSystemClipboard() : 클립보드 객체를 리턴해준다. 이 객체에 내용을 넣어 다른 프로그램등에 전달 해줄때 사용 합니다.
스레드 우선순위
* 동시성 : 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아 가며 실행하는 성질
* 병렬성 : 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질
* 스레드 스케줄링 : 스레드>코어 경우, 스레드를 어떤 순서로 실행할지 결정하는 것 : 스레드들은 번갈아가며 run() 메소드 실행
* 자바의 스레드 스케줄링 : 우선순위(Priority) 방식과 순환할당(Round-robin) 방식 사용
* 우선순위 방식 : 우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링
- 개발자가 코드로 제어 가능
- 1 ~ 10 중에서 1이 가장 우선순위가 낮음, 10이 가장 높음
- 기본적으로 모든 스레드들은 5의 우선순위를 할당 받음
- 우선순위를 변경하고 싶다면 setPriority() 메소드 이용
thread.setPriority(우선순위);
Thread 클래스 상수 이용
thread.setPriority(Thread.MAX_PRIORITY); 10
thread.setPriority(Thread.NORM_PRIORITY); 5
thread.setPriority(Thread.MIN_PRIORITY); 1
* 순환 할당 방식 : 시간 할당량을 정해 하나의 스레드를 정해진 시간만큼 실행, 다시 다른 스레드를 실행
- 개발자가 코드로 제어 불가능 : 자바 가상 기계(JVM)에 의해 정해지기 때문