java 에서는 JDK 가 모든 스레드의 속성과 메서드를 스레드 클래스로 압축한다.
그러므로 새 스레드 객체부터 생성 해야함
스레드 객체 자체는 기본적으로 비어 있기 때문에 Runnable
인터페이스를 구현하는 클래스의 객체를 해당 생성자에 전달해야함.
스레드의 start()
로 스레드 시작 가능 → JVM이 새 스레드를 생성해 운영체제에게 전달
바로 실행되는게 아닌것을 알아두자
run()
에 넣은 코드를 운영체제가 스케쥴링 하자마자 새 스레드에서 실행!
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//Code that will run in a new thread
System.out.println(2);
}
});
// 현재 스레드의 객체를 가져오는 것
Thread.currentThread();
//스레드의 이름 지정
thread.setName("New Worker Thread");
// 우선 순위 지정
//maxPriority, minPriority 가능
thread.setPriority(Thread.MAX_PRIORITY);
// 스레드 시작
thread.start();
// 해당 코드 실행 결과는?
System.out.println(1);
thread.start();
System.out.println(3);
1→2→3 ❌
정답은 그때그때 다름 ⭕️
이유는 ?
스레드가 실행되는 것은 운영체제에 의해서 결정되는 것.
thread.setUncaughtExceptionHandler로 처음부터 전체 스레드에 해당되는 예외 핸들러를 지정 가능
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("A critical error happened in thread " + t.getName()
+ " the error is " + e.getMessage());
}
});
class Thread
는 Runnable
인터페이스가 이미 구현되어져 있다.
class Thread
는 java 의 모든 스레드 관련 기능을 캡슐화 해서 제공한다.
그러므로 필요한 메서드를 @Override 해주면 된다.
private class NewThread extends Thread {
@Override
public void run() (
// this 로 현재 스레드 가르키기 가능.
this.getName();
}
}
따로 class 를 만드는 장점
- 객체 지향 프로그래밍 가능
- 상속 계층 생성 가능
- 스레드 그룹의 공통적인 기능 캡슐화 가능
TIP. abstract class 의 장점 - 그룹의 공통적 기능을 캡슐화 할 수 있음
Question 1:
애플리케이션에서 여러 개의 스레드를 사용하는 이유는 무엇일까요?
멀티스레딩은 병행성과 병렬성을 활용할 수 있게 해주어, 이를 통해 더 나은 반응성과 성능을 갖출 수 있습니다.
Question 2:
하나의 프로세스에 속한 다수의 스레드는 다음 항목을 공유합니다.
- 힙
- 코드
- 프로세스의 열린 파일
- 프로세스의 메타 데이터
Question 3:
운영 체제는 어떤 방식으로 스레드 스케줄링을 설계하나요?
스케줄링 스레드에 대한 알고리즘은 OS마다 다르고 꽤 복잡하지만, OS 는 각 스레드에 대한 동적 우선 순위를 유지하여 인터랙티브 스레드를 우선시하고 시스템의 특정 스레드가 기아상태가 되는 것을 방지한다.
Question 1:
이 코드는 어떤 작업을 수행하나요?
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Executing from a new thread");
}
});
새 스레드를 생성하는 코드이다. 이 스레드를 시작하고 OS에게 스레드를 실행하라고 명령 하고 싶으면 start()를 호출해야한다.
Question 2:
이 프로그램의 결괏값으로 올바른 문장을 선택하세요.
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I'm going for a walk");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I'm going to swim");
}
});
thread1.start();
thread2.start();
System.out.println("I'm going home");
실행 순서는 정의 할 수 없음. 서로 다른 스레드에서 실행 되기 때문.
Question 3:
코드 스니펫 1:
public class Main {
public static void main(String [] args) {
Thread thread = new TaskThread1();
thread.start();
}
public static class TaskThread1 extends Thread {
@Override
public void run(){
System.out.println("Hello from new thread");
}
}
}
****
코드 스니펫 2:
public class Main {
public static void main(String [] args) {
Thread thread = new Thread(new Task2());
thread.start();
}
public static class Task2 implements Runnable {
@Override
public void run(){
System.out.println("Hello from new thread");
}
}
}
다음 중 올바른 문장을 선택하세요.
둘 다 모두 맞음. 코드를 구성하는 방식의 차이. 일부 개발자들은 코드와 스레딩 기능을 분리하는 편을 선호하고, 또 Runnable 구현하는 편을 선호. 다른 시나리오의 경우, 개발자들은 스레딩 기능을 하나의 클래스 안에 포함시키는 편을 선호하며 따라서 스레드를 확장하는 편을 선호. 어느 방식이 맞고, 어느 방식은 틀리다고 할 수 없음.