스레드(thread)

김용민·2023년 4월 10일
0
post-thumbnail

ヾ(•ω•`)o 스레드란?

하나의 요리를 만들기 위해서는 다양한 재료들을 필요로 합니다.
또한, 이러한 재료들은 각각의 특성에 맞게 다른 방식으로 처리되어야 합니다.
예를 들어, 채소는 다듬어져야 하고, 고기는 구워야 합니다.

이를 동시에 채소를 다듬으면서, 고기도 구우면서를 한번에 진행하는 것을 말합니다

좀 더 프로그래밍 적으로 들어가게 된다면, 프로그램은 CPU가 하나의 처리를 하게 되는데
요즘 나오는 CPU가 쿼드코어 이상이 나오게 되는데 2000년대 후반까지는 단일 CPU의 속도를 올려서 만들게 됬다면 이후에는 다중코어 프로세스와 하이퍼 스레딩 기술이 등장하면서 단일 CPU보다는 다중 코어를 사용하는 것이 더 효과적으로 바뀌었습니다

결론은 ! 쓰레드는 여러가지 일을 한번에 하는 것과 같이 한번에 프로그램을 여러개 돌리는 것이다!

ヾ(•ω•`)o 스레드를 간단하게 알아보자!

  • 스레드 클래스(객체)에서 자주 쓰는 메서드들
(Thread객체명).start() 해당하는 스레드를 실행시킨다
(Thread객체명).run() 보통 객체 생성시에 오버라이드 해야되는 메서드, Thread는 일종의 추상 클래스 이기 때문에 runnable을 implements한 클래스를 넣어서 생성하거나, 익명 클래스를 이용해서 만들어야 함. 실행 했을때의 실행하는 코드를 적는 부분이다
Thread.sleep(숫자(millisecond)) static메서드, sleep(숫자)를 입력하면 그 코드를 실행할때 그 시간(들어간숫자 / 1000)만큼 딜레이 한 후 다음 코드를 실행한다

정말 자주 무조건 쓰는 메서드는 위와 같고, 그 코드를 쓰는 방법들을 보도록 합시다! !

package thread;

class PrintNumber extends Thread {
	
	@Override
	public void run() {
		for(int i = 1; i <= 25; i++) {
			System.out.print(i + " ");
		}
		System.out.println();
	}
}

class PrintAlphabet extends Thread {

	@Override
	public void run() {
		for(char ch = 'A' ; ch <= 'Z' ; ch++) {
			System.out.print(ch + " ");
		}
		System.out.println();
	}
	
	
}

public class Ex05 {
	public static void main(String[] args) {
		
		Thread th1 = new PrintNumber();
		Thread th2 = new PrintAlphabet();
		
//		th1.run();	// 내용을 작성해도, run으로 호출하면 다중 스레드 형식으로 수행되지 않는다
//		th2.run();
		
		th1.start();
		th2.start();
	}
}

위의 코드는 A ~ Z 까지의 알파벳을 순서대로 출력하는 PrintAlphabet과

1 ~ 25 까지의 숫자를 출력하는 PrintNumber를 각각 다른 쓰레드를 통해 출력하는 메서드이다

실행코드를 먼저 보자면

각각의 클래스들을 먼저 보자면

class PrintNumber extends Thread {
	
	@Override
	public void run() {
		for(int i = 1; i <= 25; i++) {
			System.out.print(i + " ");
		}
		System.out.println();
	}
}

PrintNumber 클래스는 java.lang.Thread클래스를 상속을 받았으며(기본적으로 java.lang.*은 import되어있다)

Thread는 추상 클래스의 일종이므로 무조건 run을 override해야 한다!

위에서 언급했듯 run()은 그 쓰레드를 실행했을때의 실행되는 로직이다

PrintAlphabet도 똑같이 이런 로직이 적혀 있으며

Thread th1 = new PrintNumber();
Thread th2 = new PrintAlphabet();

th1스레드에서는 숫자를 순서대로 출력하는 PrintNumber()를,

th2 스레드에서는 알파벳을 순서대로 출력하는 PrintAlphabet()을 진행하기로 정하고

th1.start();
th2.start();

그 지정한 스레드 두개를 실행시킵니다!

그래서 실행하게 되면

요론식으로 섞여서 나오게 됩니다!

그런데, 만약에 스레드를 쓰려고 한다. 스레드를 쓰려고 하는 클래스가 다음과 같이 이미 상속을 받은 상태라면? 어떻게 해야할까? 상속을 해야하는데 java에서는 다중상속이 안되는데 어떻게 해야할까? ㅜㅜ

ヾ(•ω•`)o 이미 상속이 되어있는 클래스에 스레드를 적용 시켜보기!

class PrintN extends Object implements Runnable {
	
	@Override
	public void run() {
		for(int i = 1; i<= 25; i++) {
			System.out.print(i + " ");
		}
	}
}

그럴땐! java는 다중상속은 안되지만 인터페이스는 다중으로 받을 수 있기에

Runnable 인터페이스를 구현해서 스레드를 사용합니다!

Runnable 인터페이스는 함수형 인터페이스로 그 안에 메서드 run밖에 없어서 run을 오버라이딩 해줘야 합니다!!

package thread;

class PrintN extends Object implements Runnable {
	
	@Override
	public void run() {
		for(int i = 1; i<= 25; i++) {
			System.out.print(i + " ");
		}
	}
}

public class Example {
	public static void main(String[] args) {
		
		PrintN ob = new PrintN(); 	// Runnable 객체
		Thread th1 = new Thread(ob);// 생성자 매개변수에 전달
		
		// 함수형 인터페이스 Runnable을 람다식으로 객체 생성하여 Thread의 생성자 매개변수에 전달
		Thread th2 = new Thread(() ->{
			for(char ch = 'A'; ch <= 'Z'; ch ++) {
				System.out.print(ch + " ");
			}
		});
		
		th1.start();				// 호출은 항상 Thread의 start()
		th2.start();
		
	}
}

아래와 같이 바로 람다식으로 적어도 가능! (함수형 인터페이스 이기 떄문에)

위의 코드를 실행하면 아래와 같이 실행 됩니다

이상! 간단하게 스레드를 사용하는 방법을 알아 보았습니다!

profile
안녕하세요

0개의 댓글