본문 바로가기
Java/Java

쓰레드) 쓰레드란?, 멀티쓰레드, 장단점, 쓰레드 우선 순위

by 박채니 2022. 4. 3.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


프로세스(Process)란?

- 실행 중인 하나의 프로그램

- 하나의 프로세스는 하나 이상의 쓰레드와 할당 받은 자원(메모리)등이 존재

 

스레드(Thread)란?

- 프로세스 내에 실제 작업을 수행하는 작업 단위

- 싱글 스레드(single Thread)는 한 번에 하나의 작업

- 멀티 스레드(Multi Thread)는 한 번에 여러 작업이 가능 (작업 순서는 OS의 스레드 스케줄링을 따름)

 

싱글 쓰레드의 예

public void test1() {
	taskA();
	taskB();
}
	
public void taskA() {
	for(int i = 0; i < 1000; i++) 
		System.out.print("+");
}
	
public void taskB() {
	for(int i = 0; i < 1000; i++) 
		System.out.print("|");
}

싱글 스레드의 경우, 한 번의 하나의 작업만을 수행하기 때문에 순차적으로 taskA의 print("+") 작업을 수행한 후 끝이 나서야 taskB의 print("|") 작업을 수행하기 때문에 너무 당연하게도 위와 같은 출력 결과가 나왔습니다.

 

그렇다면 멀티 쓰레드는 어떨까요?

① 쓰레드 클래스 작성 - Thread 상속

public class MyThreadA extends Thread {

}

 

1-1. run() 메소드를 오버라이딩하여 쓰레드가 실행할 내용을 작성

public class MyThreadA extends Thread {
	@Override
	public void run() {
		new ThreadBasicStudy().taskA();
	}
}

class MyThreadB extends Thread {
	@Override
	public void run() {
		new ThreadBasicStudy().taskB();
	}
}

 

1.2 start() 메소드를 통해 run() 메소드에서 오버라이딩한 쓰레드 실행 내용 실행

Thread th1 = new MyThreadA();
Thread th2 = new MyThreadB();
th1.start();
th2.start();

싱글 쓰레드를 이용하였을 때와 상이한 결과가 나온 것을 확인할 수 있습니다.

그 이유는 스레드 스케줄링(스레드를 어떤 순서로 동시성으로 실행할 것인가를 결정)으로 인해서 th1와 th2가 번갈아가면서 run() 메소드를 실행하였기 때문입니다.

싱글 스레드에서는 한 번의 하나의 작업만을 수행하기 때문에 순차적으로 "+", "|"가 찍혔다면 멀티 쓰레드는 스레드 스케줄링에 의해 번갈아가면서 실행이 되어 순서가 뒤죽박죽인 것이죠.

 

② 쓰레드 클래스 작성 - Runnable 인터페이스 구현 (다중구현 가능하므로 추천!)

public class CustomThreadA implements Runnable {

}

 

2-1. run() 메소드를 오버라이딩하여 쓰레드가 실행할 내용을 작성

public class CustomThreadA implements Runnable {
	@Override
	public void run() {
		new ThreadBasicStudy().taskA();
	}
}

class CustomThreadB implements Runnable {
	@Override
	public void run() {
		new ThreadBasicStudy().taskB();
	}
}

 

2.2 start() 메소드를 통해 run() 메소드에서 오버라이딩한 쓰레드 실행 내용 실행

Runnable run1 = new CustomThreadA();
Thread th1 = new Thread(run1);
Thread th2 = new Thread(new CustomThreadB());		
th1.start();
th2.start();

Thread 클래스를 상속하여 구현하였을 때와 동일하게 "+"과 "|"가 번갈아가면서 출력되는 것을 확인할 수 있습니다.

(start()할 때마다 스케줄링이 실행되기 때문에 실행될 때마다 결과값이 동일하진 않음)

 

Runnable 인터페이스를 구현하는 것이 다중 구현으로 인한 다중 상속이 가능하기 때문에 더 추천!합니다.

 

쓰레드의 장단점

☞ 쓰레드의 장점

① 자원을 보다 효율적으로 사용② 사용자에 대한 응답성 향상③ 작업이 분리되어 코드가 간결

 

☞ 쓰레드의 단점

① 동기화(Synchroniztion)에 주의② 교착 상태가 발생하지 않도록 주의③ 프로그래밍시 고려해야 할 사항이 많음


또한, 쓰레드 간의 우선 순위를 결정해줄 수도 있는데요,

쓰레드 우선순위 정하기

//쓰레드 우선순위
//1(우선순위 낮음) ~ 5(기본값) ~ 10(우선순위 높음)
th1.setPriority(Thread.MAX_PRIORITY);
th2.setPriority(Thread.MIN_PRIORITY);

드라마틱한 차이는 없어보이지만, 쓰레드의 실행 순위를 정해줄 수도 있습니다.