데몬쓰레드는 무엇일까?

 

- 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행.

- 일반 쓰레드가 모두 종료되면 자동적으로 종료된다.

- 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용된다.

- 무한루프와 조건문을 이용해서 실행 후 대기하다가 특정조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.

 

 

 

무한루프를 해놓아도 일반 쓰레드가 종료되면 자동적으로 종료되기 때문에 상관 없음.

 

boolean isDaemon() - 쓰레드가 데몬 쓰레드인지 확인한다.

void setDaemon(boolean on) - 쓰레드를 데몬 쓰레드로 또는 사용자 쓰레드로 변경

매개변수 on을 true로 지정하면 데몬 쓰레드가 된다.

 

setDaemon(boolean on)은 반드시 start()를 호출하기 에 실행되어야 한다.

그렇지 않으면 IllegalThreadStateException이 발생한다.

 


음.. 코드에 주석으로 설명을 대신합니다

package ThreadPt;

public class ThreadSave implements Runnable{
	static boolean autosave = false; // 자동저장 false로 꺼놓음.

	public static void main(String[] args) {
		Thread t = new Thread(new ThreadSave());
		t.setDaemon(true); // true를 하면 데몬쓰레드가 생성됨
		t.start();

		for(int i=0; i<10; i++) {
			try {
				Thread.sleep(1000); //지연시간 1초로 줍니다.
			} catch (InterruptedException e) {}
			System.out.println(i);
			// i가 5가되면 true로 바뀝니다.
			if(i==5) {autosave = true;}
		}
		System.out.println("프로그램 종료");
	}

	// Runnable인터페이스 사용하려면 run 메서드를 오버라이딩 해야합니다.
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3 * 1000); // 3초마다 3*1000이 가독성에 더 좋음.
			} catch (InterruptedException e) {}

			if(autosave) autosave();
		}
		
	}

	public void autosave() {
		/* 실제 저장 코드가 들어오면 됨 */
		System.out.println("저장되었습니다.");
	}
	
}

뭔가 while문이여서 계속 돌아갈거 같지만.. 일반 쓰레드가 없으면 자동 종료됩니다.

 

여기서 t.setDaemon(true); 이 부분을 주석 처리하면 ( ? ) 

데몬스레드는 종료되지 않습니다!!

 


쓰레드의 상태

쓰레드의 상태에는 총 5가지 상태가 있다.

 

NEW - > RUNNABLE -> BLOCKED -> WATING, TIMED_WAITING -> TERMINATED

 

차례차례 정리하자면,

 

쓰레드를 생성하면 (NEW) 상태이고

 

그 다음 start()메서드를 이용해서 RUNNABLE(줄서기) 단계에 들어갑니다.

 

자기 차례가 오면 실행됨.

 

stop()이라는 메서드를 사용하거나 작업이 마치면 Terminated 상태 소멸 상태로 변하게 됩니다.

 

suspend() = 일시정지

sleep() = 잠자기

wait() = 기다리기

join() = 다른 스레드 기달리기

I/O block = 입출력 대기

 

실행을 하는데 I/O BLOCK 때문에 걸리면 일시정지 (쉼터) 대기실에 가서 대기하고 있습니다. BLOCKED

 

쓰레드는 무엇일까? 

쓰레드 : 프로세스 내에서 실제 작업을 수행 , 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다.

프로세스 : 실행 중인 프로그램 , 자원(resources)과 쓰레드로 구성되어 있음.

작업관리자(Ctrl + Alt + Delete)  -> 오른쪽 마우스 버튼 ( 열 선택 ) -> 스레드 

작업 관리자를 통해서 지금 사용중인 프로그램에서도 스레드가 프로세스 내에서 몇개 존재하는지 확인이 가능하다.

 

프로세스가 공장이라고 하면 쓰레드는 일꾼이라고 생각하면 된다.

 

프로그램을 가동할 때, 한명의 쓰레드(일꾼)만 있으면 공장이 효율적으로 안돌아간다고 생각하면 된다.

 

그렇다면, 싱글 쓰레드와 멀티 쓰레드는 무엇인가 ? 간단하게 말하자면 

 

싱글 쓰레드 프로세스 

= 자원 + 쓰레드

 

멀티 쓰레드 프로세스

= 자원 + 쓰레드 + 쓰레드 + ... + 쓰레드

 


쓰레드의 장단점

 

쓰레드의 장점 😍

- 시스템 자원을 보다 효율적으로 사용 가능 !

- 사용자에 대한 응답성(responsiveness)이 향상 !

- 작업이 분리되어서 코드가 더 간결해 진다.

 

쓰레드의 단점 😰

- 동기화(synchronization)에 주의해야 한다.

- 교착상태(dead-lock)이 발생하지 않도록 주의해야 한다.

- 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다.


쓰레드를 만드는 방법에는 두 가지 방법이 있습니다.

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

package ThreadPt;

public class Thread1 {

	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		t1.start();
	}
}

class MyThread extends Thread{
	@Override
	public void run() { // Thread클래스를 상속해서 쓰레드를 구현
		/* 쓰레드 작업 내용 */
	}
}

1. 클래스를 만들어주고 Thread를 상속받습니다.

2. run()메서드를 오버라이딩 해주고, 작업내용을 run()메서드 안에 적어줍니다.

3. 메인메써드로 돌아와서 쓰레드를 생성해주고, start() 메서드를 이용해서 쓰레드를 실행해줍니다.

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

package ThreadPt;

public class Thread1 {
	public static void main(String[] args) {
		Runnable r = new MyThread2();
		Thread t2 = new Thread(r);
		t2.start();
		}
	}
}
class MyThread2 implements Runnable{
	@Override
	public void run() {
    		/* 동일하게 쓰레드 작업 내용 */
		}
	}
}

1. Runnable인터페이스를 구현한 클래스를 만들어줍니다.

2. run메서드를 오버라이딩해주고

3. 구현한 인터페이스를 생성해주고 쓰레드를 만든 후, 동일하게 시작해줍니다.


package ThreadPt;

public class Thread1 {

	public static void main(String[] args) {
	MyThread t1 = new MyThread();
	
	Runnable r = new MyThread2();
	Thread t2 = new Thread(r);
	
	t1.setPriority(7); // 우선 순위를 7로 설정했습니다 !
	t1.start();
	t2.start();

	}

}

class MyThread extends Thread{

	@Override
	public void run() { // Thread클래스를 상속해서 쓰레드를 구현
		for(int i=0; i<1000; i++) {
			System.out.print("1"); // 조상인 Thread의 getName()을 호출
		}
	}
	
}

class MyThread2 implements Runnable{

	@Override
	public void run() {
		for(int i=0; i<1000; i++) {
			// Thread.currentThread() - 현재 실행중인 Thread를 반환한다.
			System.out.print("2");
		}
	}
	
}

t1.setPriority(7); 의 코드가 없으면 결과 값이 엉켜서 나옵니다.

 

111212121112222111 이런식... 작업이 번갈아 실행되는 것을 확인 할 수 있습니다.

112111111222222112 OS가 쓰레드를 알아서 실행시키는 것이므로 알수가 없습니다...

그것은 OS 스케쥴러의 문제 !! ( 저는 몰라용... )

t1.setPriority(7);

이 코드를 이용하면 쓰레드에 우선 순위를 지정할 수 있습니다.

기본적으로 쓰레드의 우선 순위는 5 이고 범위는 1 ~ 10 까지 있습니다.

우선순위가 꼭 높더라도 우선 순위를 참고할뿐이지 꼭 높은작업이 먼저 끝나는 것은 아닙니다.

 


쓰레드의 실행 단계

쓰레드의 실행 단계를 살펴보면 

 

쓰레드를 생성 - > start() 메서드를 이용

package ThreadPt;

public class Thread1 {

	public static void main(String[] args) { // 메인쓰레드 !
		MyThread t1 = new MyThread();
		t1.start();
	}
}

class MyThread extends Thread{
	@Override
	public void run() { // Thread클래스를 상속해서 쓰레드를 구현
		/* 쓰레드 작업 내용 */
	}
}

아까의 코드에서 쓰레드를 찾아보자면, MyThread 하나 같지만

main도 쓰레드입니다.

그래서 main쓰레드가 먼저 호출스택에 올라가고 ,

start메서드가 실행되면 새로운 호출스택이 생기고 run 메서드를 그 호출스택에 올려주는 것

여기까지가 start메서드 역할이 종료됩니다.

 

그러면 이제 메인쓰레드에서도 코드가 돌아가고 run메서드에서도 코드가 돌아갈 수 있습니다.

서로 독립적인 작업을 수행이 가능합니다.

 


쓰레드의 I/O 블락킹(blocking)

I/O 블락킹이란 Input/Output 입출력 작업중일때 입력을 기다릴때 프로그램이 멈춘다..

해당 코드를 실행하면

	public static void main(String[] args) {
		String input = JOptionPane.showInputDialog("아무값이나 입력하세요");
		System.out.println("당신이 입력하신값은 : " + input + " 입니다.");
		
		for(int i=10; i>0; i--) {
			System.out.println(i);
			try {
				Thread.sleep(1000); // 1초간 시간을 지연한다.
			} catch (Exception e) {
				
			}
		}
	}

 

이렇게 입력하는 대화상자가 나오는데

 

입력을 하지않으면 반복문이 돌지않는다. 

이렇게 에엥이라고 입력한 후, 반복문이 돌기때문에 프로그램이 사용자의 입력하는 것을 기다리게 만든다.

 

그러면 멀티쓰레드를 이용하면 기다리지 않고 바로 실행되면서, 내용을 적으면 바로 에엥이 나온다 !

package ThreadPt;

import javax.swing.JOptionPane;

public class Thread2Multi {

	public static void main(String[] args) {
		Th2 th = new Th2();
		th.start();
		
		String input = JOptionPane.showInputDialog("아무값이나 입력하세요");
		System.out.println("당신이 입력하신값은 : " + input + " 입니다.");
	}

}
class Th2 extends Thread{

	@Override
	public void run() {
		for(int i=10; i>0; i--) {
			System.out.println(i);
			try {
				sleep(1000);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
}

 

 

카톡을 할때도 동영상이나 이미지를 전송했는데

멀티 쓰레드를 이용하지 않았다면 전부 기다리고 채팅을 보낼 수 있다.

+ Recent posts