[Java] Thread의 run과 start

JeongYong Park·2023년 6월 5일
1
post-thumbnail

코드스쿼드에서 수업을 듣던 중 다음과 같은 질문이 나왔습니다.

이 코드에서 run으로 실행시킨 것과 start로 실행시킨 것의 차이를 아나요?

어떤 차이가 있는지 정확히 몰라 이번 기회에 작성해보려 합니다.

Thread?

먼저 스레드 는 프로세스 내의 작업의 실행주체입니다. 두 개 이상의 스레드를 가진 프로그램을 멀티스레드 프로그램이라 합니다.

Java에서는 일반 스레드(Normal Thread)데몬 스레드(Daemon Thread)가 존재합니다. JVM에서 생성되는 모든 스레드에서 메인 스레드를 제외한 나머지 스레드가 데몬 스레드입니다.

데몬 스레드?

데몬 스레드는 일반 스레드를 돕는 보조적 역할을 담당하는 스레드입니다. 그렇기 때문에 일반 스레드에 종속적이며 일반 스레드가 종료되면 데몬 스레드는 강제 종료되는 특징을 가지고 있습니다.

스레드의 생성

자바에서 스레드를 생성하는 방법은 다음과 같은 두 가지 방법이 있습니다.
1. Thread 클래스를 상속

class Task extends Thread {

		@Override
		public void run() {
			System.out.println("스레드의 작업 내용입니다.");
		}
	}
}

Thread 클래스를 상속 받은 후 run 메서드를 오버라이딩하여 스레드의 작업 내용을 정의합니다.

  1. Runnable 인터페이스를 구현
class Task implements Runnable {

		@Override
		public void run() {
			System.out.println("스레드의 작업 내용입니다.");
		}
	}
}

Runnable 인터페이스를 구현한 후 마찬가지로 run 메서드를 오버라이딩 합니다.

이중 Runnable 인터페이스를 구현하는 방법으로 스레드를 생성해 run과 start의 차이를 알아보도록 하겠습니다.

run과 start

아래는 스레드의 작업내용입니다. 단순히 자신의 이름을 출력하고 1초를 쉬는 과정을 3번 반복하는 내용입니다.

	private static Consumer<String> task = (threadName) -> {
		for (int i = 0; i < 3; i++) {
			System.out.println("[" + threadName + "] START!" + " " + Thread.currentThread().getName());

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	};

run

먼저 run 메서드를 통해 스레드의 작업을 수행해보겠습니다.

	public static void main(String[] args) {
		Thread t1 = new Thread(() -> task.accept("thread1"));
		Thread t2 = new Thread(() -> task.accept("thread2"));
		Thread t3 = new Thread(() -> task.accept("thread3"));

		t1.run();
		t2.run();
		t3.run();
	}

run을 통해 스레드를 실행시키면 스레드가 순서대로 실행되는 것을 확인할 수 있습니다. 또한 모두 main 스레드에 의해 실행되는 것을 확인할 수 있습니다.

start

이번에는 start 메서드를 통해 스레드의 작업을 수행해 보겠습니다.

	public static void main(String[] args) {
		Thread t1 = new Thread(() -> task.accept("thread1"));
		Thread t2 = new Thread(() -> task.accept("thread2"));
		Thread t3 = new Thread(() -> task.accept("thread3"));

		t1.start();
		t2.start();
		t3.start();
	}

start 메서드를 통해 스레드를 실행시키면 스레드의 실행이 일관되지 않고 무작위로 실행되는 것을 확인할 수 있습니다.

왜 이런 결과가 나오는 걸까?

위의 결과만으로는 알 수 없는 내용이 하나 더 있습니다. 스레드의 작업이 수행될 때 run 방식은 스레드 하나씩 실행되고 start 방식은 스레드 1, 2, 3이 동시에 실행된다는 차이가 있었습니다.

왜 이런 결과가 나오는 걸까요?

run 방식은 단순히 오버라이딩한 run() 메서드를 호출하는 것이고, start는 새로운 스레드를 생성하고 필요한 call stack을 생성한 후 run()을 호출하기 때문입니다.

결론

  • 자바에서 스레드의 작업을 수행하는 방법은 run과 start 메서드를 호출하는 방법이 있다.
  • run은 단순히 오버라이딩한 run() 메서드를 호출하는 것이기 때문에 병렬적으로 실행되는 것이 아닌 main 스레드 위에서 순차적으로 실행되는 것이다.
  • start 방식은 새로운 스레드를 생성해서 각각의 call stack 생성하고 그곳에서 run() 메서드를 호출하는 것이기 때문에 작업이 병렬적으로 실행된다.

참고 자료

https://medium.com/@lunay0ung/thread-daemon-thread-3b89ce606b04

https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

https://javarevisited.blogspot.com/2012/03/difference-between-start-and-run-method.html#axzz83ijanRit

profile
다음 단계를 고민하려고 노력하는 사람입니다

0개의 댓글