✔️ 멀티 스레드
: 하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행
- 각 스레드가 자신이 속한 프로세스의 메모리를 공유
✔️ 멀티 프로세스
: 여러 개의 CPU를 사용하여 여러 프로세스를 동시에 수행
- 각 프로세스가 독립적인 메모리를 가지고 별도로 실행
➡️ 둘 모두 여러 흐름을 동시에 수행하다는 공통점을 가지고 있다.
⭐️ 장점
❌ 단점
: 멀티스레드 프로그래밍을 의미
: 멀티코어 프로그래밍을 의미
➡️ 우리가 살펴 볼 것은 병행 프로그래밍
✏️ 메인 스레드(Main Thread)
- 모든 자바 애플리케이션은 메인 스레드(main thread)가 main() 메소드를 실행하면서 시작된다.
멀티스레드를 배움으로써 메인 스레드 안에서 새로운 스레드를 생성할 수 있다.
✔️ 다른 일반 스레드의 작업을 돕는 보조적인 역할을 하는 스레드
✔️ 일반 스레드가 종료되면 데몬 스레드는 강제적으로 자동 종료됨
데몬 스레드는 일반 스레드가 모두 종료되면 더는 할 일이 없으므로, 데몬 스레드 역시 자동으로 종료된다.
이러한 데몬 스레드는 백그라운드 작업에서 활용된다.
포그라운드에서 작업이 끝날 때 백그라운드도 같이 종료돼야 하는데 이것을 데몬스레드로 처리한다.
또한 일정 시간마다 자동으로 수행되는 저장 및 화면 갱신, 가비지 컬렉터 등에도 이용되고 있다.
📎 가비지 컬렉터(gabage collector)
: 프로그래머가 동적으로 할당한 메모리 중 더 이상 사용하지 않는 영역을 자동으로 찾아내어 해제해 주는 데몬 스레드
데몬 스레드의 생성 방법과 실행 방법은 모두 일반 스레드와 같다.
- void setDaemon(boolean ..): 스레드를 데몬 스레드 또는 일반 스레드로 변경
- boolean isDaemon(): 스레드가 데몬 스레드인지 확인. 맞으면 true 반환
❗️setDaemon(boolean ..)
은 반드시 start()
메서드를 호출하기 전에 실행되어야 한다. 그렇지 않으면 IllegalThreadStateException
이 발생한다.
public class NormalThreadTest {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
try {
System.out.println("MyThread 시작");
Thread.sleep(5000); //
System.out.println("MyThread 종료");
} catch (Exception e) {
}
}
};
t.start();
System.out.println("main() 종료");
}
}
main() 종료
MyThread 시작
MyThread 종료
모든 스레드가 종료되어야 프로그램이 종료된다는 것을 확인 할 수 있다.
public class DeamonThreadTest {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
try {
System.out.println("MyThread 시작");
Thread.sleep(5000);
System.out.println("MyThread 종료");
} catch (Exception e) {}
}
};
// 반드시 start() 호출 전에 사용해야 한다!
// 데몬스레드
t.setDaemon(true);
t.start();
System.out.println("main() 종료");
}
}
main() 종료
MyThread 시작
일반 스레드와 비교했을 때, 주 스레드가 종료되자 같이 종료되어버렸다.
✔️ 멀티스레드의 순서를 정하는 것
: 우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링 하는 것
: setPriority()
메소드를 사용하여 우선순위를 설정
: 우선순위는 1에서 10까지 부여할 수 있고 1이 가장 낮고 10이 가장 높다.
// Thread 상속
class SomeThread extends Thread {
public SomeThread(String name) {
super(name);
}
@Override
public void run() {
String name = this.getName();
for(int i = 0; i < 10; i++) {
System.out.println(name + " is working");
try {
Thread.sleep(500);
} catch (Exception e) {}
}
}
}
public class RunningTest {
// main thread는 우선순위가 NORM_PRIORITY(5) 이다.
public static void main(String[] args) {
SomeThread t1 = new SomeThread("A");
SomeThread t2 = new SomeThread("B");
SomeThread t3 = new SomeThread("C");
t1.setPriority(Thread.MIN_PRIORITY); // = 1
t2.setPriority(Thread.NORM_PRIORITY); // = 5
t3.setPriority(Thread.MAX_PRIORITY); // = 10
t1.start();
t2.start();
t3.start();
}
}
A is working
B is working
C is working
B is working
A is working
C is working
A is working
B is working
C is working
B is working
C is working
A is working
C is working
A is working
B is working
A is working
B is working
C is working
A is working
B is working
C is working
B is working
C is working
A is working
A is working
B is working
C is working
A is working
C is working
B is working
우선순위가 높은 스레드를 무조건 실행하게 하는 것이 아니고 확률이 약간 더 올라간다.
100%가 아니기 때문에 우선순위에 의존해서 선택하지 않는다.
C가 먼저 동작하는 경우는 없지만 아예 없는 것도 아니다.
즉, 우선 순위를 제일 높게 설정한다고 항상 먼저 실행됨을 보장 할 수는 없다.
: 시간 할당량(Time Slice)을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식
References
: https://cornswrold.tistory.com/187
: https://cafe.naver.com/javachobostudy