[CS/운영체제] 멀티스레드와 동시성 - 2부

황제연·2025년 6월 25일
0

CS학습

목록 보기
116/193
post-thumbnail

자바의 Thread 생성 방법

자바에서 스레드를 사용하려면 Thread 객체를 생성하면 됩니다

public class threadTest extends Thread{
	@Override
	public void run(){
		System.out.println(Thread.currentThread().getName() + ", test");
	}

}

메인스레드에서 위와같이 다른 스레드를 호출하는 방법은 두가지 방법이 있습니다

public class Main{
	public static void main(String[] args){
		threadTest.start();
		threadTest.run();
	}
}

start는 Thread-0 스택을 새로 만들어서 해당 스택에서 스레드 작업을 실행합니다
하지만 run은 메인스레드에서 해당 작업을 실행합니다
따라서 해당 스레드 작업도 main 스레드 스택에서 진행합니다

start로 실행할 경우, 다른 스레드 스택에서 작업을 진행하기 때문에
스레드는 순서와 실행 기간을 모두 보장하지 않습니다

데몬 스레드

스레드는 사용자 스레드와 데몬 스레드 2가지로 분류할 수 있습니다

사용자 스레드

프로그램의 주요 작업을 수행하며, 작업이 완료될 때가지 실행됩니다
모든 사용자 스레드가 종료되면 JVM도 종료됩니다

데몬 스레드

백그라운드에서 보조적인 작업을 수행합니다
모든 사용자 스레드가 종료되면 데몬 스레드는 자동으로 종료됩니다

주의할 점은 JVM은 데몬 스레드의 실행 완료를 기다리지 않고 종료합니다
데몬 스레드가 아닌 모든 스레드가 종료되면 자바 프로그램도 종료됩니다

demonThread.setDaemon(true);

해당 명령어를 통해서 데몬 스레드 여부를 지정할 수 있습니다

스레드 생성 - Runnable

자바가 제공하는 Runnable 인터페이스를 구현하는 방식으로도 스레드를 사용할 수 있습니다

public class threadRunnableTest implements Runnable{
	@Override
	public void run(){
		System.out.println(Thread.currentThread().getName() + ", test");
	}

}

다만 Thread 객체를 생성할때 실행할 작업을 생성자로 전달해야합니다

public class Main{
	public static void main(String[] args){
		threadRunnableTest runnable = new threadRunnableTest();
		Thread thread = new Thread(runnable);
		thread.start();
	}
}

Thread 상속 vs Runnable 구현

스레드를 사용할 때는 Thread를 상속 받는 방법보다는
Runnable 인터페이스를 구현하는 방식을 사용하는 것이 좋습니다

Thread 클래스 상속방식

장점

Thread 클래스를 상속받아 run() 메소드만 재정의하면 됩니다

단점

자바는 단일 상속만 허용하기 때문에, 다른 클래스를 상속받고 있으면 Thread 클래스를 상속받을 수 없습니다
또한 인터페이스를 사용하는 방법에 비해 유연성이 떨어집니다

Runnable 인터페이스를 구현하는 방식

장점

Runnable 인터페이스 방식은 다른 클래스를 상속받아도 문제없이 구현할 수 있습니다
또한 스레드와 실행할 작업을 분리해서 코드의 가독성을 높이고
여러 스레드가 동일한 Runnbale 객체를 공유할 수 있어 자원관리를 효율적을 할 수 있습니다

단점

Runnable 객체를 생성하고 이를 Thread에 전달하는 과정이 추가되므로
코드가 약간 복잡해질 수 있습니다

다수의 스레드를 실행한다면?

다수의 스레드를 실행한다면 실행순서가 보장될까요?

public class Main{
	public static void main(String[] args){
		threadRunnableTest runnable = new threadRunnableTest();
		Thread thread1 = new Thread(runnable);
		thread1.start();
		Thread thread2 = new Thread(runnable);
		thread2.start();
		Thread thread3 = new Thread(runnable);
		thread3.start();
	}
}

위 스레드는 모두 같은 threadRunnableTest 인스턴스를 스레드의 실행작업으로 전달했습니다
따라서 모든 스레드는 같은 인스턴스에 있는 run 메소드를 실행합니다

참고로 위 결과를 실행할 때마다 스레드 실행순서가 달라집니다
즉, 스레드의 실행순서는 보장되지 않습니다

기타

자바에서 Runnable을 만드는 방법은 다양합니다
1. 정적 중첩 클래스
2. 익명 클래스
3. 람다
위 3가지 방법으로 Runnable을 만들 수 있습니다

참고

  • 김영한의 실전 자바 - 고급 1편
profile
Software Developer

0개의 댓글