멀티 쓰레드
2025. 11. 30. 21:39ㆍJAVA/JAVA의 기초 개념
멀티 쓰레드의 장단점
- 멀티 쓰레드는 장점이 많지만, 고려해야할 사항도 많이 있습니다.
| 장점 | 시스템 자원을 보다 효율적으로 사용할 수 있다. |
| 사용자에 대한 응답성이 향상된다. | |
| 작업이 분리되어 코드가 간결해 진다. | |
| 단점 | 동기화에 주의해야 한다.(서로 충돌이 많을 수 있다) |
| 교착상태가 발생하지 않도록 주의해야 한다. | |
| 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다. |
쓰레드의 구현과 생성
- run()에 쓰레드가 수행할 내용을 작성하는 2가지 방법
1.Thread클래스를 상속
public class MyThread extends Thread{
public void run(){
//구현 내용 // -> // Thread의 run()을 오버라이딩
}
}
2.Runnable인터페이스를 구현
public class MyThread implements Runnable{
public void run(){
//구현 내용 // -> // Runnable의 run()을 구현
}
}
3.현재 쓰레드 확인
public class Main {
public static void main(String[] args) throws IOException {
// 1. 쓰레드 생성
MyThread myThread = new MyThread();
// 2. 쓰레드 실행
myThread.start();
}
}
// 1.쓰레드를 상속받아서 run()을 오버라이딩
class MyThread extends Thread{
public void run(){
for(int i = 0; i<10; i++){
System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
}
}
}
run()을 직접 구현해 현재 쓰레드 이름을 출력하게 작성을 진행했습니다.

4.멀티쓰레드 동작 확인
public class Main {
public static void main(String[] args) throws IOException {
// 1. 쓰레드 생성
MyThread myThread = new MyThread();
Thread thread = new Thread(new MyThread1());
// 2. 쓰레드 실행
myThread.start();
thread.start();
}
}
// 1.쓰레드를 상속받아서 run()을 오버라이딩
class MyThread extends Thread{
public void run(){
for(int i = 0; i<10; i++){
System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
}
}
}
class MyThread1 implements Runnable{
public void run(){
for(int i = 0; i<10; i++){
System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
}
}
}

5.start()와 run()
- start()는 새로운 호출 스택을 생성하고, run()을 호출
6.쓰레드의 우선순위(priority of thread)
- 쓰레드 마다 우선순위를 다르게 지정 가능.
void setPriority(int newPriority) // 쓰레드의 우선순위를 지정한 값으로 변경한다.
int getPriority() // 쓰레드의 우선순위를 반환한다.
public static final int MAX_PRIORITY = 10; //최대 우선 순위
public static final int MIN_PRIORITY = 1; //최소 우선 순위
public static final int NORM_PRIORITY = 5; //보통 우선 순위
7.데몬 쓰레드(daemon thread)
- 보조족인 역할을 수행, 모든 일반 쓰레드가 종료되면, 자동 종료
boolean isDaemon() // 쓰레드가 데몬 쓰레드인지 확인. 데몬 쓰레드면 true
void setDaemon(boolean on) 쓰레드를 데몬 쓰레드로 또는 사용자 쓰레드로 변경
매개변수 on의 값을 true로 하면 데몬 쓰레드가 된다.
※참고 setDaemon(boolean on)은 반드사 start()를 호출하기 전에 실행되어야 한다.
public class DaemonThread {
static boolean save = false;
public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.setDaemon(true);
t.start();
for(int i = 1; i<=100; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(i);
if(i == 5) save = true;
}
System.out.println("프로그램 종료");
}
static class MyThread implements Runnable{
@Override
public void run() {
while (true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if(save){
System.out.println("저장완료");
}
}
}
}
}
setDaemon을 true로 하면 무한 루프에 코드가 종료 되는 것을 파악할 수 있습니다.

그 이유는 데몬 쓰레드는 쓰레드 종료시 자동으로 종료 되기 때문입니다.
그렇다면 false로 한다면 어떻게 될까?

프로그램이 끝나도 지속적으로 실행되는 것을 파악할 수 있습니다.
8.쓰레드 실행 제어
쓰레드의 실행을 제어하는데 사용하는 메서드
| static void sleep(long millis) | 지정된 시간(천분의 일초 단위)동안 쓰레드를 일시 정지시킨다. 지정한 시간이 지나고 나면, 자동적으로 다시 실행 대기 상태가 된다. sleep()는 JDK 19부터 추가. |
| static void sleep(long millis,int nanos) | |
| static void sleep(Duration duration) | |
| void join() | 지정된 시간동안 쓰레드가 실행되도록 한다. 지정된 시간이 지나거나 작업이 종료되면 join()을 호출한 쓰레드로 다시 돌아와 실행을 계속한다. join()은 JDK 19부터 추가 |
| void join(long millis) | |
| void join(long millis,int nanos) | |
| void join(Duration duration) | |
| void interrupt() | sleep()이나 join()에 의해 일시 정시 상태인 쓰레드를 깨워서 실행 대기 상태로 만든다. InterruptedException이 발생하여 일시 정지 상태를 벗어나게 된다. |
| static void yield() | 실행 중에 자신에게 주어진 실행시간을 다른 쓰레드에게 양보(yield) 자신은 실행 대기 상태가 된다. |
※참고 resume(), stop(), suspend()는 쓰레드를 교착상태로 만들기 쉽기 때문에 deprecated되었다.
쓰레드의 상태
| 상태 | 설명 |
| NEW | 쓰레드가 생성되고 아직 start()가 호출되지 않은 상태 |
| RUNNABLE | 실행 중 또는 실행 가능 상태 |
| BLOCKED | 동기화 블럭에 의해서 일시정지된 상태(lock이 풀릴 때까지 기다리는 상태) |
| WAITING, TIMED_WAITING |
쓰레드의 작업이 종료되지는 않았지만, 실행가능하지 않은 일시정지 상태. TIMED_WAITING은 일시정시시간이 지정된 경우를 의미한다. |
| TERMINATED | 쓰레드의 작업이 종료된 상태. |