JAVA,Spring
[멀티스레드와 동시성] - 스레드(Thread)
devkdh
2025. 9. 18. 20:43
스레드란?
스레드란 하나의 프로세스에서 동시에 실행될 수 있는 독립적인 실행 흐름 단위이다.
자바 어플리케이션은 기본적으로 하나의 메인 스레드로 실행되지만 여러개의 스레드를 생성하면 동시실행이 가능하다.
사용법
Thread 클래스를 상속하거나, Runnable 인터페이스를 구현한 후, start()매소드를 호출해서 실행할 수 있다.
Tread 클래스 상속
Thread 클래스를 상속받고, run() 매소드를 오버라이드 하는 방식
class GetMessage extends Thread{
@Override
public void run(){
System.out.println("메시지 수신 스레드 실행 중: "+ Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
GetMessage getMessage = new GetMessage();
getMessage.start();
}
}실행 결과
메시지 수신 스레드 실행 중: Thread-0이때 start() 매소드가 아닌 run()매소드를 호출하면 현재 스레드에서 실행된다.
start()매소드를 호출해야 새로운 스레드를 만든다.
start()는 OS 시스템 콜을 통해 실제 스레드를 생성하고, 그 스레드에서 run()을 실행한다.
아래 코드는 이를 보여주는 예시이다.
class Test extends Thread{
@Override
public void run(){
System.out.println("테스트 스레드 실행 중: "+ Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
Test useRun = new Test();
Test useStart = new Test();
System.out.println("run() 매소드 사용");
useRun.run();
useStart.run();
System.out.println("start() 매소드 사용");
useRun.start();
useStart.start();
}
}실행 결과
run() 매소드 사용
테스트 스레드 실행 중: main
테스트 스레드 실행 중: main
start() 매소드 사용
테스트 스레드 실행 중: Thread-0
테스트 스레드 실행 중: Thread-1## Runnable 인터페이스 구현하기
class Task implements Runnable{
@Override
public void run(){
System.out.println("작업 실행 중: " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
Runnable task = new Task();
Thread thread = new Thread(task);
thread.start();
}
}실행결과
작업 실행 중: Thread-0스레드의 예외처리
스레드 내부에서 예외가 발생하면 그 스레드는 종료되고 예외가 발생했다는 사실조차 알 수 없다.
따라서 반드시 명시적인 예외처리가 필요하다.
class Test extends Thread{
@Override
public void run(){
System.out.println("테스트 스레드 실행 중: "+ Thread.currentThread().getName());
throw new RuntimeException("에러 발생!!");
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("메인 스레드는 죽지 않는다.");
}
}실행 결과
메인 스레드는 죽지 않는다.
테스트 스레드 실행 중: Thread-0
Exception in thread "Thread-0" java.lang.RuntimeException: 에러 발생!!
at Test.run(Main.java:7)
종료 코드 0(으)로 완료된 프로세스Thread-0 이 에러를 뱉어도 메인스레드는 종료되지 않고 실행되는 모습이다.
그럼 main스레드에서 이를 알려면 어떻게 해야할까?
스레드 내부에서 try-catch 로 직접 예외 감싸기
class Test extends Thread{
@Override
public void run(){
try{
System.out.println("테스트 스레드 실행 중: "+ Thread.currentThread().getName());
throw new RuntimeException("에러 발생!!");
}catch (Exception e){
System.out.println("예외 처리: "+ e.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("메인 스레드는 죽지 않는다.");
}
}실행 결과
메인 스레드는 죽지 않는다.
테스트 스레드 실행 중: Thread-0
예외 처리: 에러 발생!!예외처리가 내부적으로 되기에 스레드가 죽지않고 정상적으로 종료된다.
UncaughtExceptionHandler 등록
class Test extends Thread{
public Test(){
setUncaughtExceptionHandler((t,e)->{
System.out.println("[" + t.getName() + "] 예외 발생: " + e.getMessage());
});
}
@Override
public void run(){
throw new RuntimeException("에러 발생!!");
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("메인 스레드는 죽지 않는다.");
}
}실행 결과
메인 스레드는 죽지 않는다.
[Thread-0] 예외 발생: 에러 발생!!
종료 코드 0(으)로 완료된 프로세스이 경우 스레드는 죽지만 해당 스레드를 핸들러가 감지해서 예외처리를 할 수 있다.