본문 바로가기
컴퓨터 언어/JAVA

[JAVA] 쓰레드(Thread) (1)

by 테크케찰 2020. 6. 17.

이번 포스트는 남궁 성님의 "Java의 정석"이란 책을 참고하여 작성하였습니다.

포스트 내용 중에 오류나 수정 사항이 있으면 댓글 남겨주시면 감사드리겠습니다.

 

1. 쓰레드란?

쓰레드는 프로세스의 자원을 이용해서 실제로 작업을 수행하는 친구라고 합니다.

여기서 프로세스는 프로그램을 실행시켜 동작하게 만든 것입니다.

쓰레드는 하나의 프로세스에서 한 개 이상 존재하며 쓰레드가 여러 개 있으면 하나의 일을 동시에 수행할 수 있습니다.

 

2. 쓰레드 생성

쓰레드를 구현하는 방법은 두 가지가 있습니다.

1) Thread 클래스를 상속하는 방법

public class Main {
	public static void main(String args[]) {
		Thread1 thread1=new Thread1();
		thread1.start(); //thread1 실행
	}
}

class Thread1 extends Thread{
	public void run() {System.out.println("Thread1을 실행합니다.");}
}

2) Runnable 인터페이스를 구현하는 방법

public class Main {
	public static void main(String args[]) {
		Runnable r=new Thread2();
		Thread thread2=new Thread(r);
//		Thread t2=new Thread(new Thread2()); -> 위의 두 줄을 이렇게 나타낼 수도 있습니다.
		thread2.start();
	}
}

class Thread2 implements Runnable{
	public void run(){ System.out.println("Thread2를 실행합니다."); }
}

1), 2)에서 start() 메서드를 통해 쓰레드가 실행되고, 이 때 Thread1과 Thread2에서 선언된 run 메서드가 실행이 됩니다.

여기서 start()를 호출해주어야만이 쓰레드를 실행하는 것이라 볼 수 있는데요, run()을 사용하는 것은 단순히 클래스의 메서드를 호출하는 것인 반면, start()는 독립적인 호출 스택을 생성하기 때문입니다.

 

3. 멀티쓰레드

2번에서 생성한 쓰레드 클래스를 가지고 두 개의 쓰레드를 동시에 돌려보겠습니다.

 

public class Main {
	public static void main(String args[]) {
		Thread1 thread1=new Thread1();
		Runnable r=new Thread2();
		Thread thread2=new Thread(r);
		
		thread1.start();  
		thread2.start();
	}
}

class Thread1 extends Thread{
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println("Thread1 실행-"+i);
			try {
				Thread.sleep(100);  // 쓰레드 0.1초 동안 대기
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Thread2 implements Runnable{
	public void run(){ 
		for(int i=0;i<10;i++) {
			System.out.println("Thread2 실행-"+i);
			try {
				Thread.sleep(100);  // 쓰레드 0.1초 동안 대기
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 이 코드를 실행시킨 결과 값은 아래와 같습니다. 

Thread1 실행-0
Thread2 실행-0
Thread1 실행-1
Thread2 실행-1
Thread1 실행-2
Thread2 실행-2
Thread2 실행-3
Thread1 실행-3
Thread2 실행-4
Thread1 실행-4
Thread2 실행-5
Thread1 실행-5
Thread2 실행-6
Thread1 실행-6
Thread2 실행-7
Thread1 실행-7
Thread2 실행-8
Thread1 실행-8
Thread2 실행-9
Thread1 실행-9

 

 보시는 바와 같이 Thread1과 Thread2가 번갈아가면서 실행이 되면서 두 작업이 동시에 실행되고 있음을 확인하실 수 있습니다.

단순한 계산 작업 같은 경우는 싱글 쓰레드로 작업하시는 게 속도가 더 빠르고, 두 쓰레드가 서로 다른 자원을 사용하는 작업의 경우에는 멀티 쓰레드를 사용하시는 것이 더 낫다고 합니다.

 

4. 쓰레드의 우선순위

쓰레드는 우선순위를 지정할 수 있는데요, 이를 통해 어떠한 쓰레드가 더 많은 작업 시간을 가지고 더 빠르게 반응하도록 합니다.

우선순위는 1~10까지의 범위를 가지며, 높은 숫자일수록 높은 우선순위를 가집니다.

쓰레드의 우선순위를 지정하기 메서드는 아래와 같습니다.

void setPriority(int newPriority) //쓰레드의 우선순위를 newPriority 값으로 설정합니다.
int getPriority() // 쓰레드의 우선순위 값을 반환합니다

쓰레드의 우선순위를 따로 지정해주지 않는다면 기본적으로 우선순위 값은 5를 갖습니다.

이를 이용해서 앞서 3번에서 썼던 예제에 우선순위를 지정해본 후 결과 값이 어떻게 바뀌는지 알아보도록 하겠습니다.

public class Main {
	public static void main(String args[]) {
		Thread1 thread1=new Thread1();
		Runnable r=new Thread2();
		Thread thread2=new Thread(r);
		
		thread2.setPriority(10);
		
		System.out.println("Thread1의 Priority: "+thread1.getPriority());
		System.out.println("Thread2의 Priority: "+thread2.getPriority());
		
		thread1.start();  
		thread2.start();
	}
}

class Thread1 extends Thread{
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println("Thread1 실행-"+i);
			try {
				Thread.sleep(1000);  // 쓰레드 1초 동안 대기
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Thread2 implements Runnable{
	public void run(){ 
		for(int i=0;i<10;i++) {
			System.out.println("Thread2 실행-"+i);
			try {
				Thread.sleep(1000);  // 쓰레드 1초 동안 대기
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 코드를 실행한 결과 값은 아래와 같습니다.

Thread1의 Priority: 5
Thread2의 Priority: 10
Thread2 실행-0
Thread1 실행-0
Thread2 실행-1
Thread1 실행-1
Thread2 실행-2
Thread1 실행-2
Thread2 실행-3
Thread1 실행-3
Thread2 실행-4
Thread1 실행-4
Thread2 실행-5
Thread1 실행-5
Thread2 실행-6
Thread1 실행-6
Thread2 실행-7
Thread1 실행-7
Thread2 실행-8
Thread1 실행-8
Thread2 실행-9
Thread1 실행-9

코드에서 Thread2가 Thread1에 비해서 더 큰 우선순위를 가지도록 지정해주었습니다.

그 결과, 결과 값에서도 볼 수 있듯이 Thread2가 Thread1보다 먼저 실행됨을 확인할 수 있었습니다.

 

쓰레드에 대한 내용은 다룰 부분이 많아서 오늘 포스트는 여기서 마치도록 하겠습니다. 다음 번 포스트 떄 쓰레드에 대해 이어쓰도록 하겠습니다. 감사합니다 ^~^