profile image

L o a d i n g . . .

article thumbnail image
Published 2022. 7. 25. 07:05

스레드(thread)?

- 프로세스 내부에서 코드의 실행 흐름

 

프로세스?

- 애플리케이션을 실행하면 운영체제로부터 실행에 필요한 메모리를 할당받아 실행

- 실행중인 하나의 애플리케이션

 

multi?

운영체제는 두 가지 이상의 작업을 동시에 처리하는 멀티태스킹 을 할 수 있도록 CPU및 메모리 자원을 프로세스마다 적절히 할당해주고 병렬로 실행시켜준다.

ex) 미디어 플레이어로 음악을 들으며 워드로 문서작업, 게임을 하면서 카카오톡 채팅

 

다만 멀티태스킹은 항상 멀티프로세스를 뜻하는 것은 아님

 

한 프로세스내에서 멀티태스킹이 가능하기도 하다

ex) 카카오톡으로 메신저를 하면서 파일전송, 미디어플레이어로 노래감상하며 동영상재생

 

이렇게 하나의 프로세스 내에서 두 가지 이상의 작업 처리하는것을 멀티스레드로 동작한다 라고 말함

 

멀티 프로세스는 자신의 메모리를 가지고 실행하므로 서로 독립적이나,

멀티 스레드는 하나의 프로세스 내보에 생성되므로 스레드하나가 예외를 발생시키면 다른 스레드도 영향 받음

ex) 카카오톡으로 채팅을 하다가 워드가 먹통이면 워드만 종료되면 되나, 카카오톡으로 채팅하며 파일을 보낼 때 파일전송 스레드에서 예외가 발생하면 메신저 프로세스 자체가 종료되므로 채팅스레드도 같이 종료된다.

 

 

 

 

 

 

 

 


작업 스레드 생성과 실행

 

싱글 스레드 app 에서는 메인 스레드가 종료하면 프로세서 종료.

멀티스레드 app 에서는 실행 중 스레드가 하나라도 있다면 메인스레드가 작업 스레드보다 먼저 종료되더라도  프로세스 종료 안됨

 

 

 

 

 

 

멀티스레드로 실행하는 애플리케이션을 개발하려면 먼저 몇 개의 작업을 병렬로 실행할 지 결정하고 

각 작업별로 스레드를 생성해야한다.

 

어떤 자바 app이건 main()메소드를 실행하면서 시작되는 메인스레드는 반드시 존재하기 때문에 메인 작업 이외에 추가적 병렬 작업의 수만큼 스레드를 생성하면된다.

 

자바에서는 작업 스레드도 객체생성이 필요하기 때문에 클래스를 사용한다.

java.lang.Thread클래스를 직접 객체화해 생성해도 되나, Thread클래스를 상속한 하위클래스를 만들어 생성할 수도 있다

 

 

 

 

 

 

 

 


Thread 클래스로부터 직접 생성

Thread thread = new Thread(Runnable target);

java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성하려면 Runnable을 매개값으로 갖는 생성자 호출 필요

Runnable은 작업 스레드가 실행할 수 있는 코드를 갖고있는 객체라고해서 붙여진 이름.

Runnable은 인터페이스 타입이기 때문에 구현 객체를 만들어 대입해야한다.

 

class Task implements Runnable {
	public void run(){
    	//스레드가 실행할 코드;
    }
}

Runnble 구현 객체 생성 후 이것을 매개값으로 해서 Thread생성자를 호출해야 비로소 작업 스레드 생성.

코드를 절약하기 위해 Thread 생성자를 호출 시 Runnable 익명 객체를 매개값으로 사용하는 방법을 더 많이쓴다.

 

 

 

thread.start();

작업 스레드는 생성 즉시 실행되는 것이 아닌, start() 메소드를 위와같이 호출해야 실행된다.

start() 메소드가 호출되면, 작업 스레드는 매개값으로 받은 Runnable의 run() 메소드를 실행하면서 자신의 작업을 처리함

 

 

 

 

 

 

 

 

 

 


메인스레드만 이용한 경우

import java.awt.Toolkit;

public class BeepPrintEx {
	public static void main(String[] args) {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for (int i = 0; i < 5; i++) {
			toolkit.beep();
			try { Thread.sleep(500); } catch (Exception e) {}
		}
		
		for (int i = 0; i < 5; i++) {
			System.out.println("띵");
			try { Thread.sleep(500); } catch (Exception e) {}
		}
	}
}

비프음 발생과 출력은 서로 다른 작업이므로 메인스레드가 동시에 두 가지 작업을 처리할 수 없다.

따라서 메인스레드는 비프음을 모두 발생한 다음, 출력을 한다.

 

 

 

메인스레드와 작업스레드 를 이용한 경우

import java.awt.Toolkit;

public class BeepTask implements Runnable{
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for (int i = 0; i < 5; i++) {
			toolkit.beep();
			try { Thread.sleep(500); } catch (Exception e) {}
		}
	}
}

비프음 발생 코드를 다음과 같이 작업스레드 생성 및 실행코드로 변경 했다

 

 

 

public class BeelPrintEx1 {
	public static void main(String[] args) {
		Runnable beepTask = new BeepTask();
		Thread thread = new Thread(beepTask);
		thread.start(); //BeepTask 객체의 run()메소드 실행
		
		for (int i = 0; i < 5; i++) {
			System.out.println("띵");
			try { Thread.sleep(500);} catch (Exception e) {}
		}
	}
}

실행 시 소리와 함께 콘솔 출력이 이루어진다.

 

 

import java.awt.Toolkit;

public class BeepPrintEx2 {
	public static void main(String[] args) {
		Thread thread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				for (int i = 0; i < 5; i++) {
					toolkit.beep();
					try {Thread.sleep(500);} catch (Exception e) {}
				}
			}
		});
		thread.start();
		for (int i = 0; i < 5; i++) {
			System.out.println("띵");
			try {Thread.sleep(500);} catch (Exception e) {}
		}
	}
}

Runnable 익명 객체를 이용해서 구현하면 이런식으로 사용할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

참고 : 

반응형

'개발 > JAVA' 카테고리의 다른 글

[Java] 스레드 제어  (0) 2022.07.27
[Java] 멀티 스레드2  (0) 2022.07.26
[Java] java.util 패키지 내 Date, Calendar 클래스  (0) 2022.07.21
[Java] java.lang 패키지  (0) 2022.07.20
[Java] 예외처리  (0) 2022.07.18
복사했습니다!