[java] Thread


Thread

์“ฐ๋ ˆ๋“œ์˜ ๊ฐœ๋… ๋ฐ ๊ธฐ๋ณธ ์˜ˆ์ œ


ํ”„๋กœ์„ธ์Šค์™€ ์“ฐ๋ ˆ๋“œ

ํ”„๋กœ์„ธ์Šค

์šด์˜์ฒด์ œ์—์„œ๋Š” ์‹คํ–‰์ค‘์ธ ํ•˜๋‚˜์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ”„๋กœ์„ธ์Šค๋ผ๊ณ  ํ•จ.

์šด์˜์ฒด์ œ๋กœ๋ถ€ํ„ฐ ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น๋ฐ›์•„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰.

์“ฐ๋ ˆ๋“œ

ํ”„๋กœ์„ธ์Šค๋ฅผ ์ด๋ฃจ๋Š” ์ฝ”๋“œ์˜ ์‹คํ–‰ํ๋ฆ„.

ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋Š” ํ•˜๋‚˜์˜ ์ฝ”๋“œ ์‹คํ–‰ํ๋ฆ„์ž„.

๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค

์„œ๋กœ ๋…๋ฆฝ์ . ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Œ.

๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ

ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋ฉด ํ”„๋กœ์„ธ์Šค ํ•˜๋‚˜๊ฐ€ ์•„์˜ˆ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ -> ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ค‘์š”.

๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ

์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ๊ฐ€ main ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด์„œ ์‹œ์ž‘ํ•จ.


์“ฐ๋ ˆ๋“œ์˜ ์ƒ์„ฑ

1.Thread ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ง์ ‘ ์ƒ์„ฑ

Thread thread = new Thread(Runnable target);

- ์ง์ ‘ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Runnable ํƒ€์ž…์„ ๋งค๊ฐœ๊ฐ’์œผ๋กœ ๊ฐ–๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•จ.

- Runnable์€ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์ธ๋ฐ run ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ์–ด Runnable ๊ตฌํ˜„๊ฐ์ฒด๋Š” run ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•จ.

- Runnable ๊ตฌํ˜„๊ฐ์ฒด๋ฅผ ์ง์ ‘ Class๋กœ ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ต๋ช…๊ฐ์ฒด๋ฅผ ์ด์šฉ(์ฃผ๋กœ ์“ด๋‹ค๊ณ  ํ•จ.)ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Œ.

- ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” run ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์ด ์•„๋‹Œ start()๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•จ.

Runnable taskrun = new Task();
Thread thread = new Thread(taskrun);
Thread threadanony = new Thread( new Runnable(){
	public void run(){
    	//์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ํ•  ์ฝ”๋“œํ๋ฆ„	
    }
});

2.Thread ํ•˜์œ„ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ.

- Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•ด์•ผํ•จ.

import java.awt.Toolkit;

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

- 0.5์ดˆ๋งˆ๋‹ค ๋น„ํ”„์†Œ๋ฆฌ๋ฅผ ๋‚ด๋Š” ์“ฐ๋ ˆ๋“œ ํ•˜์œ„ ํด๋ž˜์Šค ์ƒ์„ฑ.

import java.awt.Toolkit;

public class BeepPrintExample3 {
	public static void main(String[] args) {
		Thread thread = new BeepThread();
		
		//2. ใ…‡์ต๋ช…๊ฐ์ฒด
		Thread thread2 = new Thread() {
			@Override
			public void run() {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				for(int i =0; i<5; i++) {
					toolkit.beep();
					try {Thread.sleep(500);} catch(Exception e) {}
				}
			}
		};
		
		
		thread2.start();
		
		for(int i =0; i<5; i++) {
			System.out.println("๋ต");
			try {Thread.sleep(500);} catch(Exception e) {}
		}
	}
}

- ๋ต ์ถœ๋ ฅ๊ณผ ๋ต ๋น„ํ”„์Œ์ด ๊ฑฐ์˜ ๋™์‹œ์— ์ˆ˜ํ–‰๋˜๋Š”๊ฒƒ์ฒ˜๋Ÿผ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ.


์“ฐ๋ ˆ๋“œ์˜ ์ด๋ฆ„ ์ •์˜

- ์“ฐ๋ ˆ๋“œ๋Š” ์“ฐ๋ ˆ๋“œ๋งˆ๋‹ค ์ด๋ฆ„์ด ์žˆ์Œ.

- ํฐ ์—ญํ• ์„ ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋””๋ฒ„๊น…ํ• ๋•Œ ์–ด๋–ค ์“ฐ๋ ˆ๋“œ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋‚ด๋Š”์ง€ ์กฐ์‚ฌํ•  ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ํ•จ.

- ์ด๋ฆ„์„ ์ฃผ์ง€ ์•Š์€ ์“ฐ๋ ˆ๋“œ๋Š” โ€œThread-nโ€์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์„ค์ •๋จ.

- setName(โ€œ์“ฐ๋ ˆ๋“œ์ด๋ฆ„โ€) ์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ช…์„ ์„ค์ •๊ฐ€๋Šฅ.

- getName() ๋ฉ”์†Œ๋“œ๋กœ ์“ฐ๋ ˆ๋“œ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜.

thread.setName("์“ฐ๋ ˆ๋“œ๋ช…");
thread.getName(); // ์“ฐ๋ ˆ๋“œ๋ช… ๋ฐ˜ํ™˜

- currentThread()๋กœ ํ˜„์žฌ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋Š” ์“ฐ๋ ˆ๋“œ์˜ ์ฐธ์กฐ๋ฅผ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ์Œ

Thread thread = Thread.currentThread();

๊ฐ„๋‹จ ์˜ˆ์ œ

public class ThreadNameExample {
	public static void main(String[] args) {
		Thread mainThread = Thread.currentThread();
		System.out.println("ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์“ฐ๋ ˆ๋“œ ์ด๋ฆ„: "+mainThread.getName());
		
		ThreadA threadA = new ThreadA();
		System.out.println("์ž‘์—… ์“ฐ๋ ˆ๋“œ ์ด๋ฆ„ : "+threadA.getName());
		threadA.start();
		
		ThreadB threadB = new ThreadB();
		System.out.println("์ž‘์—… ์“ฐ๋ ˆ๋“œ ์ด๋ฆ„ : "+threadB.getName());
		threadB.start();
		
	}
}
//-----------------------------------
public class ThreadA extends Thread{
	public ThreadA() {
		setName("ThreadA");
	}
	
	@Override
	public void run() {
		for(int i =0; i<2; i++) {
			System.out.println(getName()+"๊ฐ€ ์ถœ๋ ฅํ•œ ๋‚ด์šฉ");
		}
	}
}
//-----------------------------------
public class ThreadB extends Thread{
	@Override
	public void run() {
		for(int i =0; i<2; i++) {
			System.out.println(getName()+"๊ฐ€ ์ถœ๋ ฅํ•œ ๋‚ด์šฉ");
		}
	}
}


์“ฐ๋ ˆ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„ ๊ฐœ๋…

์“ฐ๋ ˆ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„

๋™์‹œ์„ฑ : ๋ฉ€ํ‹ฐ์ž‘์—…์„ ์œ„ํ•ด ํ•˜๋‚˜์˜ ์ฝ”์–ด์—์„œ ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰ํ•˜๋Š” ์„ฑ์งˆ

๋ณ‘๋ ฌ์„ฑ : ๋ฉ€ํ‹ฐ์ž‘์—…์„ ์œ„ํ•ด ๋ฉ€ํ‹ฐ ์ฝ”์–ด์—์„œ ๊ฐœ๋ณ„ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” ์„ฑ์งˆ

img1 daumcdn


์“ฐ๋ ˆ๋“œ ์Šค์ผ€์ค„๋ง

- ์“ฐ๋ ˆ๋“œ์˜ ๊ฐฏ์ˆ˜๊ฐ€ ์ฝ”์–ด์˜ ์ˆ˜๋ณด๋‹ค ๋งŽ์„ ๊ฒฝ์šฐ์— ์“ฐ๋ ˆ๋“œ๋ฅผ ์–ด๋–ค ์ˆœ์„œ์— ์˜ํ•ด ๋™์‹œ์„ฑ์œผ๋กœ ์‹คํ–‰ํ•  ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•œ ๊ณ„ํš.

- ์•„์ฃผ ์งง์€ ์‹œ๊ฐ„ ์“ฐ๋ ˆ๋“œ์˜ run ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰ํ•œ๋‹ค.

##### ์šฐ์„ ์ˆœ์œ„(priority)๋ฐฉ์‹

- ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰์ƒํƒœ๋ฅผ ๋” ๋งŽ์ด ๊ฐ€์ ธ๊ฐ.

- ๊ฐ์ฒด์— ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ์–ด๊ฐ€๋Šฅ.

- 1๋ถ€ํ„ฐ 10๊นŒ์ง€ ์šฐ์„ ์ˆœ์œ„, ๋†’์œผ๋ฉด ๋จผ์ € ์‹คํ–‰

thread.setPriority(์šฐ์„ ์ˆœ์œ„);

์šฐ์„ ์ˆœ์œ„ ์ƒ์ˆ˜ : Thread.MAX_PRIORITY(10), Thread.NORM_PRIORITY(5), Thread.MIN_PRIORITY(1)

- ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๊ธฐํšŒ๋ฅผ ๋” ๋งŽ์ด ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋” ๋‚ฎ์€ ์“ฐ๋ ˆ๋“œ๋ณด๋‹ค ๊ฐ™์€ ์ž‘์—…์ด๋ผ๋„ ๋นจ๋ฆฌ ๋๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

- ํ•˜์ง€๋งŒ ์ฟผ๋“œ ์ฝ”์–ด์ผ ๊ฒฝ์šฐ ์“ฐ๋ ˆ๋“œ๊ฐ€ 4๊ฐœ ๋ณด๋‹ค ์ ์„ ๊ฒฝ์šฐ๋Š” ์šฐ์„ ์ˆœ์œ„๊ฐ€ ํฌ๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ๋ชปํ•œ๋‹ค. 5๊ฐœ์ด์ƒ์ผ๋•Œ ์šฐ์„ ์ˆœ์œ„ ๋ฐฉ์‹์ด ํšจ๊ณผ๋ฅผ ๋ณด๊ฒŒ ๋œ๋‹ค.

public class PriorityExample {
	public static void main(String[] args) {
		for(int i =1; i<=10; i++) {
			Thread thread = new ClacThread("thread"+i);
			if(i == 10) {
				//๊ฐ€์žฅ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„
				thread.setPriority(Thread.MAX_PRIORITY);
			}else {
				//๊ฐ€์žฅ ๋†’์€ ์šฐ์„ ์ˆœ์œ„
				thread.setPriority(Thread.MIN_PRIORITY);
			}
			thread.start();
		}
	}
}
//---------------------------------------------------------
public class ClacThread extends Thread{
	public ClacThread(String name) {
		setName(name);
	}
	
	public void run() {
		for(int i =0; i<2000000000; i++) {}
		System.out.println(getName());
	}
}
์ˆœํ™˜ ํ• ๋‹น(Round-robin) ๋ฐฉ์‹

- ์‹œ๊ฐ„ํ• ๋‹น๋Ÿ‰(Time Slice)์„ ์ •ํ•ด ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ •ํ•ด์ง„ ์‹œ๊ฐ„๋งŒํผ๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ์‹.

- JVM์— ์˜ํ•ด์„œ ์ •ํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋กœ ์ œ์–ด ๋ถˆ๊ฐ€๋Šฅ


์“ฐ๋ ˆ๋“œ ๋™๊ธฐํ™” ๋ฉ”์†Œ๋“œ, ๋™๊ธฐํ™” ๋ธ”๋Ÿญ

๊ณต์œ  ๊ฐ์ฒด ์‚ฌ์šฉ์‹œ

- ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ์˜ ๊ฒฝ์šฐ๋Š” ๊ณ ๋ฏผํ•  ๊ฒฝ์šฐ๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค.

- ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ์˜ ๊ฒฝ์šฐ ์“ฐ๋ ˆ๋“œ๊ฐ„์˜ ํ•˜๋‚˜์˜ ๊ฐ์ฒด ๊ณต์œ  ์‹œ ๋””๋ฒ„๊น…ํ•˜๊ธฐ ์–ด๋ ค์šด ์˜ค๋ฅ˜๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค.

img1 daumcdn

Tread-1์ด ๊ณต์œ ๊ฐ์ฒด์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜์— ํ• ๋‹น๋œ ๊ฐ’์„ ๋ณ€๊ฒฝ. -> ๊ทธ์‚ฌ์ด Thread-2๊ฐ€ ๊ณต์œ  ๊ฐ์ฒด์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜์— ํ• ๋‹น๋œ ๊ฐ’์„(null์ด ์•„๋‹Œ์ง€ ๋ชจ๋ฅด๊ณ ) ์—Ž์–ด์นจ. -> Thread-1 ๊ณต์œ ๊ฐ์ฒด ์‚ฌ์šฉํ•˜๋ ค๋Š”๋ฐ ๊ฐ’์ด๋ฐ”๋€œ-> ์˜ค๋ฅ˜

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ž„๊ณ„์˜์—ญ์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด์— ์ž ๊ธˆ์„ ๊ฑธ์–ด๋‘์–ด ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ์ด ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์“ฐ๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค.

ํ‚ค์›Œ๋“œ : synchronized

๋™๊ธฐํ™”(synchronized) ๋ฉ”์†Œ๋“œ

public synchronized void method(){
	//์ž„๊ณ„์˜์—ญ; ๋‹จํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์‹คํ–‰๊ฐ€๋Šฅ.
}
package sync;

public class Calculator {
	private int memory;
	
	public int getMemory() {
		return memory;
	}
	//๋™๊ธฐํ™” ๋ฉ”์†Œ๋“œ๋กœ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•
	public synchronized void setMemory(int memory) { 
		this.memory = memory;
		try {
			Thread.sleep(2000);
		}catch(InterruptedException e) {}
		System.out.println(Thread.currentThread().getName()+" : "+this.memory);
	}
}

- setMemory ๋ฉ”์†Œ๋“œ๋Š” ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ์ด ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ฉ”์†Œ๋“œ

๋™๊ธฐํ™”(synchronized) ๋ธ”๋Ÿญ

public void method(){
	synchronized (๊ณต์œ ๊ฐ์ฒด){
    	//์ž„๊ณ„์˜์—ญ(๋‹จ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅ)
    }
    //์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์˜์—ญ.
}
package sync;

public class Calculator {
	private int memory;
	
	public int getMemory() {
		return memory;
	}
	
	// ์ด๋ ‡๊ฒŒ ๋™๊ธฐํ™” ๋ธ”๋Ÿญ์„ ์‚ฌ์šฉํ•ด์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
	public void setMemory(int memory) {
		synchronized (this) {
			this.memory = memory;
			try {
				Thread.sleep(2000);
			}catch(InterruptedException e) {}
			System.out.println(Thread.currentThread().getName()+" : "+this.memory);
		}
	}
}


์“ฐ๋ ˆ๋“œ์˜ ์ƒํƒœ์ œ์–ด ๋ฉ”์†Œ๋“œ ๋ฐ ๋ฐ๋ชฌ ์“ฐ๋ ˆ๋“œ ๊ฐœ๋…

์“ฐ๋ ˆ๋“œ์˜ ์ƒํƒœ์ œ์–ด

- ์‹คํ–‰์ค‘์ธ ์“ฐ๋ ˆ๋“œ์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ.

- ๋ฉ”์†Œ๋“œ๋กœ ์ฃผ๋กœ ์ œ์–ด

- interrupt(), sleep(), join(), wait(), yield() notify(), notifyAll() ๋“ฑ์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ์กด์žฌ.

- ์ด์ค‘ notify(), notifyAll(), wait() ๋ฉ”์†Œ๋“œ๋Š” Object ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ์ด๊ณ  ๋‚˜๋จธ์ง€๋Š” Thread ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ.

์ผ์ •์‹œ๊ฐ„๋™์•ˆ ์ผ์‹œ์ •์ง€ : sleep()

- ์‹คํ–‰์ค‘์ธ ์“ฐ๋ ˆ๋“œ๋ฅผ ์ผ์‹œ์ •์ง€.

- ๋งค๊ฐœ๊ฐ’์œผ๋กœ ๋ฐ€๋ฆฌ์ดˆ๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ํ•ด๋‹น ์‹œ๊ฐ„๋™์•ˆ sleep() ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋Š” ์“ฐ๋ ˆ๋“œ๋Š” ์ผ์‹œ์ •์ง€ํ•จ.

- ์ผ์‹œ์ •์ง€ ์ƒํƒœ์—์„œ interrupt() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ InterruptedException์ด ๋ฐœ์ƒ๋จ.

try{
	Thread.sleep(1000); //1์ดˆ๊ฐ„ ์ผ์‹œ์ •์ง€(๋ฐ€๋ฆฌ์ดˆ : 1000 -> 1์ดˆ)
}catch(InterruptedException){
	//interrupt() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์‹คํ–‰.
}

ํƒ€ ์“ฐ๋ ˆ๋“œ์— ์‹คํ–‰ ์–‘๋ณด : yield()

- ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ˜๋ณต์ž‘์—…์„ ์œ„ํ•ด for๋ฌธ์ด๋‚˜ while๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ.

public void run(){
	while(true){
    	if(work){
        	System.out.println("ThreadA ์ž‘์—… ๋‚ด์šฉ");
        }
    }
}

-์ด๋•Œ while๋ฌธ์€ boolean ํƒ€์ž… work ๋ณ€์ˆ˜๊ฐ€ false ์ผ๊ฒฝ์šฐ์—๋Š” ์“ธ๋ฐ์—†๋Š” ๋ฃจํ”„๋ฅผ ๋Œ๊ฒŒ๋จ.

- yield() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ˜ธ์ถœํ•œ ์“ฐ๋ ˆ๋“œ๋Š” ์‹คํ–‰๋Œ€๊ธฐ์ƒํƒœ๋กœ ๋Œ์•„๊ฐ€๊ณ  ๋™์ผํ•œ ์šฐ์„ ์ˆœ์œ„ ํ˜น์€ ๋†’์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ–๋Š” ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ๊ธฐํšŒ๋ฅผ ๊ฐ–๊ฒŒ๋จ.

public class ThreadA extends Thread{
	public boolean stop = false; //์ข…๋ฃŒ ํ”Œ๋ž˜๊ทธ
	public boolean work = true; // ์ž‘์—…์ง„ํ–‰์—ฌ๋ถ€
	
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println("ThreadA ์ž‘์—… ๋‚ด์šฉ");
			}else {
				Thread.yield();
			}
		}
		System.out.println("ThreadA ์ข…๋ฃŒ");
	}
}

- ThreadA๊ฐ€ else ๋ฌธ์œผ๋กœ yield ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด ํ˜„์žฌ Thread ๊ฐ์ฒด์ธ ThreadA์˜ run ๋ฉ”์†Œ๋“œ๋Š” ์‹คํ–‰๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋˜๊ณ  ThreadB๊ฐ€ ์‹คํ–‰๊ธฐํšŒ๋ฅผ ๊ฐ–๋Š”๋‹ค.

๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ์˜ ์ข…๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆผ : join()

- ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜์–ด์•ผ ์‹คํ–‰ํ•ด์•ผํ•˜๋Š” ์“ฐ๋ ˆ๋“œ๊ฐ€ ์กด์žฌ

- ๊ณ„์‚ฐ์ž‘์—…์ด ๊ทธ ์˜ˆ์ธ๋ฐ, ๊ณ„์‚ฐํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ return ํ•˜๋Š” ์“ฐ๋ ˆ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ๊ทธ๊ฒƒ์„ ์ถœ๋ ฅํ•˜๋Š” ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ•„์š”ํ•œ๋ฐ

- ๊ทธ ๋•Œ ์ถœ๋ ฅ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋จผ์ € ์ˆ˜ํ–‰๋˜๋ฉด ์˜ค๋ฅ˜์ž„.

public class SumThread extends Thread{
	private long sum;

	public long getSum() {
		return sum;
	}

	public void setSum(long sum) {
		this.sum = sum;
	}

	public void run() {
		for(int i =1; i<=100; i++) {
			sum+=i;
		}
	}
	
	@Override
	public String toString() {
		return "SumThread [sum=" + sum + "]";
	}
}

public class JoinExample {
	public static void main(String[] args) {
		SumThread sumThread = new SumThread();
		sumThread.start();
		
		try {
			sumThread.join();//ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ ๊ธฐ์ค€ (์ด๋ถ€๋ถ„์„ ์ฃผ์„์ฒ˜๋ฆฌํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ๋น„๊ตํ•ด๋ณด์„ธ์š”)
		} catch (Exception e) {
		}
		System.out.println("1~100 ํ•ฉ : "+sumThread.getSum());
	}
}

- ์—ฌ๊ธฐ์„œ ์ถœ๋ ฅ์“ฐ๋ ˆ๋“œ๋Š” ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋‹ด๋‹นํ•œ ๊ฒƒ์ž„.

์“ฐ๋ ˆ๋“œ๊ฐ„ ํ˜‘๋ ฅ : wait() , notify() , notifyAll()

- ๋‘๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰

- ํ•ต์‹ฌ์€ ๊ณต์œ ๊ฐ์ฒด์˜ ํ™œ์šฉ

- ๋‘ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ž‘์—…ํ•  ๋‚ด์šฉ์„ ๋™๊ธฐํ™” ๋ฉ”์†Œ๋“œ๋กœ ๊ตฌ๋ถ„.

- ์“ฐ๋ ˆ๋“œ1 ์ž‘์—… ์™„๋ฃŒ -> notify() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ -> (์ผ์‹œ์ •์ง€)์“ฐ๋ ˆ๋“œ 2 ์‹คํ–‰๋Œ€๊ธฐ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ -> ์“ฐ๋ ˆ๋“œ 1์€ wait() (์ผ์‹œ์ •์ง€ ์ƒํƒœ)

- ์ด๋“ค ๋ฉ”์†Œ๋“œ๋Š” ๋™๊ธฐํ™” ๋ฉ”์†Œ๋“œ ํ˜น์€ ๋™๊ธฐํ™” ๋ธ”๋ก์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ.

//๊ณต์œ ๊ฐ์ฒด
public class WorkObject {
	public synchronized void methodA() {
		System.out.println("ThreadA์˜ methodA() ์ž‘์—… ์‹คํ–‰");
		notify(); //์ผ์‹œ์ •์ง€ ์ƒํƒœ์— ์žˆ๋Š” ThreadB๋ฅผ ์‹คํ–‰๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋งŒ๋“ฌ.
		try {
			wait();//ThreadA๋ฅผ ์ผ์‹œ์ •์ง€ ์ƒํƒœ๋กœ ๋งŒ๋“ฌ.
		} catch (Exception e) {
		}
	}
	
	public synchronized void methodB() {
		System.out.println("ThreadB์˜ methodB() ์ž‘์—… ์‹คํ–‰");
		notify(); //์ผ์‹œ์ •์ง€ ์ƒํƒœ์— ์žˆ๋Š” ThreadA๋ฅผ ์‹คํ–‰๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋งŒ๋“ฌ.
		try {
			wait();//ThreadB๋ฅผ ์ผ์‹œ์ •์ง€ ์ƒํƒœ๋กœ ๋งŒ๋“ฌ.
		} catch (Exception e) {
		}
	}
}

//Thread A
public class ThreadA extends Thread{
	private WorkObject workObject;
	
	public ThreadA(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i =0; i<10; i++) {
			workObject.methodA();
		}
	}
}

//ThreadB
public class ThreadB extends Thread{
	private WorkObject workObject;
	
	public ThreadB(WorkObject workObject) {
		this.workObject = workObject;
	}
	
	@Override
	public void run() {
		for(int i =0; i<10; i++) {
			workObject.methodB();
		}
	}
}

//main ์“ฐ๋ ˆ๋“œ
public class WaitNotifyExample {
	public static void main(String[] args) {
		WorkObject shareObject = new WorkObject(); //๊ณต์œ ๊ฐ์ฒด ์ƒ์„ฑ
		
		ThreadA threadA = new ThreadA(shareObject);
		ThreadB threadB = new ThreadB(shareObject);//ThreadA์™€ ThreadB ์ƒ์„ฑ
		
		threadA.start();
		threadB.start();
				
	}
}

- ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ์—์„œ ๊ณต์œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ

- ๊ฐ๊ฐ์˜ ์“ฐ๋ ˆ๋“œ์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋กœ ์ดˆ๊ธฐํ™”. ๊ณต์œ  ๊ฐ์ฒด์˜ methodA์™€ methodB๋ฅผ ์‚ฌ์šฉ

- methodA์™€ methodB๋Š” ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰๋˜์–ด์•ผํ•จ.

- ์ด ํ˜‘๋ ฅ๊ฐœ๋…์—์„œ ๋ฐœ์ „ํ•˜์—ฌ ์œ ๋ช…ํ•œ ์ž๋ฐ” ๋””์ž์ธ ํŒจํ„ด์ธ ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ํŒจํ„ด์œผ๋กœ ์—ฐ๊ฒฐ๋จ.

์“ฐ๋ ˆ๋“œ์˜ ์•ˆ์ „์ข…๋ฃŒ : interrupt()

- run() ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ชจ๋‘ ์‹คํ–‰๋˜๋ฉด ์“ฐ๋ ˆ๋“œ๋Š” ์ข…๋ฃŒ๋จ.

- ๊ธฐ์กด์˜ stop() ์ด๋ž€ ๋ฉ”์†Œ๋“œ๊ฐ€ ์ œ๊ณต๋˜์—ˆ์œผ๋‚˜ deprecated ๋˜์—ˆ๋‹ค. -> ๋ฌธ์ œ

- ์™œ? -> ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋˜ ์ž์›์ด ๋ฌธ์ œ๊ฐ€ ๋  ๊ฐ€๋Šฅ์„ฑ( ์ž์›์ด๋ž€ ํŒŒ์ผ, ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ๋“ฑ)

- interrupt() ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž์›๋„ ํ•ด์ œํ•˜๋ฉฐ ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Œ.

public class PrintThread2 extends Thread{
	public void run() {
		try {
			while(true) {
				System.out.println("์‹คํ–‰ ์ค‘");
				Thread.sleep(1);
				//if(Thread.interrupted()) {
				//if(Thread.currentThread().isInterrupted()) {
					//break;
				//}
			}
		} catch (InterruptedException e) {
			System.out.println("interrupt() ์‹คํ–‰");
		}
		System.out.println("์ž์› ์ •๋ฆฌ");
		System.out.println("์‹คํ–‰ ์ข…๋ฃŒ");
	}
}

//๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ
public class InterruptExample {
	public static void main(String[] args) {
		Thread thread = new PrintThread2();
		thread.start();
		
		try {
			Thread.sleep(1000);
		} catch (Exception e) {
			
		}
		thread.interrupt();
	}
}

- ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ์—์„œ interrupt() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœํ•  ๋•Œ PrintThread2 ์“ฐ๋ ˆ๋“œ๋Š” InterruptedException์ด ๋ฐœ์ƒํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ผ์‹œ์ •์ง€์ƒํƒœ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์•„๋ฌด์˜๋ฏธ๊ฐ€ ์—†๋‹ค.

- ๊ทธ๋ž˜์„œ Thread.sleep(1) ์ฝ”๋“œ๋กœ ํ•œ๋ฒˆ ์ผ์‹œ์ •์ง€ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ์—์„œ interrupt() ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋จผ์ € ์ข…๋ฃŒํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ดํ›„ PrintThread2 ์“ฐ๋ ˆ๋“œ๋Š” ์ž์›์„ ์ •๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒํ•˜๊ฒŒ ๋œ๋‹ค.

- ์ฃผ์„์ฒ˜๋ฆฌ๋œ Thread.interrupted() ๋ฉ”์†Œ๋“œ์™€ isInterrupted() ๋ฉ”์†Œ๋“œ๋Š” ๋ชจ๋‘ interrupt() ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋ฌ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” boolean ๊ฐ’์ด๋‹ค. ์ฐธ์กฐ๊ฐ์ฒด๋ฅผ ๋ณด๋ฉด์•Œ๊ฒ ์ง€๋งŒ Thread.interrupted()๋Š” static ๋ฉ”์†Œ๋“œ์ด๊ณ , isInterrupted() ๋ฉ”์†Œ๋“œ๋Š” ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ์ด๋‹ค. ๋‘˜์ค‘ ์–ด๋–ค๊ฒƒ์„ ์‚ฌ์šฉํ•ด๋„ ์ข‹๋‹ค.

๋ฐ๋ชฌ ์“ฐ๋ ˆ๋“œ

- ์“ฐ๋ ˆ๋“œ์˜ ์ž‘์—…์„ ๋•๋Š” ๋ณด์กฐ์ ์ธ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์“ฐ๋ ˆ๋“œ.

- ์ฃผ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๋ฐ๋ชฌ์“ฐ๋ ˆ๋“œ๋Š” ๊ฐ•์ œ์ ์œผ๋กœ ์ž๋™ ์ข…๋ฃŒ.

- Java์˜ Garbage Collector๊ฐ€ ๋Œ€ํ‘œ์ ์ธ ๋ฐ๋ชฌ ์“ฐ๋ ˆ๋“œ๋ผ๊ณ  ํ•จ. - > JVM์ด ์ข…๋ฃŒ๋˜๋ฉด ๊ฐ™์ด ์ข…๋ฃŒ๋˜๋‹ˆ๊นŒ.

- ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ์—์„œ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋ฐ๋ชฌ์“ฐ๋ ˆ๋“œ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ๋ชฌ ์“ฐ๋ ˆ๋“œ๊ฐ€๋  ์“ฐ๋ ˆ๋“œ์˜ ์ฐธ์กฐ๊ฐ์ฒด์—์„œ setDaemon(true)๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

- ์ฃผ์˜์ ์€ ๋ฐ๋ชฌ์“ฐ๋ ˆ๋“œ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ start() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์ƒํƒœ๋ผ๋ฉด IllegalThreadStateException์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— start() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์กด์— setDaemon(true)๋ฅผ ์‹คํ–‰ํ•ด์•ผํ•œ๋‹ค.

public class AutoSaveThread extends Thread{
	public void save() {
		System.out.println("์ž‘์—… ๋‚ด์šฉ์„ ์ €์žฅํ•จ");
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				System.out.println("1");//์—ฌ๊ธฐ์‹คํ–‰์•ˆ๋จ. exception ๋ฐœ์ƒ์€ ์•„๋‹˜
				e.printStackTrace();
				break;
			}
			save();
		}
	}
}

//๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ
public class DaemonExample {
	public static void main(String[] args) {
		AutoSaveThread autoSaveThread = new AutoSaveThread();
		autoSaveThread.setDaemon(true);
		autoSaveThread.start();
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {

		}
		System.out.println("๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ ์ข…๋ฃŒ");
	}
}

- ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด ๊ธฐ์กด์˜ ์“ฐ๋ ˆ๋“œ๋Š” ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฃฝ์–ด๋„ ๋ฐ˜๋ณต์ž‘์—…์„ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์ž‘์—…์“ฐ๋ ˆ๋“œ๋Š” ์‚ด์•„์žˆ์–ด ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์ง€ ์•Š์•˜๋Š”๋ฐ ์œ„ ์˜ˆ์ œ๋Š” ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฃฝ์œผ๋ฉด์„œ ๋ฐ๋ชฌ์“ฐ๋ ˆ๋“œ๋„ ๊ฐ™์ด ์ฃฝ์–ด์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ์‹œํ‚จ๋‹ค.


์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน ๊ฐœ๋…

Thread Group

- ๊ด€๋ จ๋œ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•  ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ.

- JVM์ด ์‹คํ–‰๋ ๋•Œ - system ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์„ ๋งŒ๋“ฌ - JVM ์šด์˜์— ํ•„์š”ํ•œ ์“ฐ๋ ˆ๋“œ๋“ค์„ ์ƒ์„ฑ - system ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์— ํฌํ•จ์‹œํ‚ด

์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน ์ด๋ฆ„ ์–ป๊ธฐ

ThreadGroup group = Thread.currentThread().getThreadGroup();
String groupName = group.getName();

์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน ์˜ˆ์ œ

public static void main(String[] args) {
	ThreadGroup group = Thread.currentThread().getThreadGroup();
	//System.out.println(group.getName());
		
	AutoSaveThread autoSaveThread = new AutoSaveThread();
	autoSaveThread.setName("AutoSaveThread");
	autoSaveThread.setDaemon(true);
	autoSaveThread.start();
		
	Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
	Set<Thread> threads = map.keySet();
		
	for(Thread thread : threads) {
		System.out.println("Name : "+thread.getName() + ((thread.isDaemon()) ? "(๋ฐ๋ชฌ)":"(์ฃผ)"));
		System.out.println("\t"+"์†Œ์†๊ทธ๋ฃน : "+thread.getThreadGroup().getName());
		System.out.println();
	}
}

- getAllStackTraces() : ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์‹คํ–‰ํ•˜๋Š” ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์Œ.

๊ฒฐ๊ณผ

Name : Signal Dispatcher(๋ฐ๋ชฌ)  
์†Œ์†๊ทธ๋ฃน : system  
Name : AutoSaveThread(๋ฐ๋ชฌ)  
์†Œ์†๊ทธ๋ฃน : main  
Name : main(์ฃผ)  
์†Œ์†๊ทธ๋ฃน : main  
Name : Attach Listener(๋ฐ๋ชฌ)  
์†Œ์†๊ทธ๋ฃน : system  
Name : Finalizer(๋ฐ๋ชฌ) - ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ๋‹ด๋‹น.  
์†Œ์†๊ทธ๋ฃน : system  
Name : Reference Handler(๋ฐ๋ชฌ)  
์†Œ์†๊ทธ๋ฃน : system

์ž‘์—…์“ฐ๋ ˆ๋“œ๋Š” ๋Œ€๋ถ€๋ถ„ ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ์—์„œ ์ƒ์„ฑํ•œ๋‹ค. ์“ฐ๋ ˆ๋“œ์˜ ๊ทธ๋ฃน์„ ์ง์ ‘ ์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๋””ํด๋“œ๋กœ ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ์˜ ๊ทธ๋ฃน์— ์†ํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ AutoSaveThread๋Š” ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ์—์„œ ์ƒ์„ฑํ•˜์˜€์œผ๋ฏ€๋กœ ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ์˜ ๊ทธ๋ฃน์— ์†ํ•˜๋Š” main๊ทธ๋ฃน์— ์†ํ•˜์˜€๋‹ค.

ThreadGroup ํด๋ž˜์Šค๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ฃผ์š” ๋ฉ”์†Œ๋“œ

ย ๋ฉ”์†Œ๋“œ์„ค๋ช…
intactiveCount()ํ˜„์žฌ ๊ทธ๋ฃน ๋ฐ ํ•˜์œ„ ๊ทธ๋ฃน์—์„œ ํ™œ๋™์ค‘์ธ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ์˜ ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
intactiveGroupCount()ํ˜„์žฌ ๊ทธ๋ฃน์—์„œ ํ™œ๋™ ์ค‘์ธ ๋ชจ๋“  ํ•˜์œ„ ๊ทธ๋ฃน์˜ ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค
voidcheckAccess()ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์„ ๋ณ€๊ฒฝํ•  ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ์ฒดํฌํ•œ๋‹ค. ๋งŒ์•ฝ ๊ถŒํ•œ์ด ์—†์œผ๋ฉด SecurityException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค
voiddestroy()ํ˜„์žฌ ๊ทธ๋ฃน ๋ฐ ํ•˜์œ„ ๊ทธ๋ฃน์„ ๋ชจ๋‘ ์‚ญ์ œํ•œ๋‹ค. ๋‹จ, ๊ทธ๋ฃน ๋‚ด์— ํฌํ•จ๋œ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๋“ค์ด ์ข…๋ฃŒ ์ƒํƒœ๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.
booleanisDestroyed()ํ˜„์žฌ ๊ทธ๋ฃน์ด ์‚ญ์ œ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค
intgetMaxPriority()ํ˜„์žฌ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค
voidsetMaxPriority(int pri)ํ˜„์žฌ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์„ค์ •ํ•œ๋‹ค
StringgetName()ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ ์ด๋ฆ„์„ ๋ฆฌํ„ดํ•œ๋‹ค.
ThreadGroupgetParent()ํ˜„์žฌ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ ๋ถ€๋ชจ๊ทธ๋ฃน์„ ๋ฆฌํ„ดํ•œ๋‹ค.
booleanparentOf(ThreadGroup g)ํ˜„์žฌ ๊ทธ๋ฃน์ด ๋งค๊ฐœ๊ฐ’์œผ๋กœ ์ง€์ •ํ•œ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ ๋ถ€๋ชจ์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
voidsetDaemon(boolean daemon)ํ˜„์žฌ ๊ทธ๋ฃน์„ ๋ฐ๋ชฌ๊ทธ๋ฃน์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.
voidlist()ํ˜„์žฌ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ์“ฐ๋ ˆ๋“œ์™€ ํ•˜์œ„ ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
voidinterrupt()ํ˜„์žฌ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๋“ค์„ interruptํ•œ๋‹ค.

์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ ์ผ๊ด„์ ์œผ๋กœ interrupit() ํ˜ธ์ถœ

์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์ 

- ๊ทธ๋ฃน๋‚ด ํฌํ•จ๋œ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๋“ค์„ ์ผ๊ด„ interrupt() ์‹œ์ผœ์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๋Ÿฌ๋ฒˆ ํ• ๊ฑธ ํ•œ๋ฒˆ์— ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ. - ํ•˜์ง€๋งŒ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ interrupt() ๋ฉ”์†Œ๋“œ๋Š” ์†Œ์†๋œ ์“ฐ๋ ˆ๋“œ์˜ interrupt() ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰๋งŒ ํ• ๋ฟ ๊ฐœ๋ณ„ ์“ฐ๋ ˆ๋“œ์˜ InterruptedException ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋Š” ํ•˜์ง€ ์•Š๋Š”๋‹ค.

- ๊ฐœ๋ณ„ ์“ฐ๋ ˆ๋“œ์—์„œ InterruptedException ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

- ์˜ˆ์ œ

public class WorkThread extends Thread{
	public WorkThread(ThreadGroup threadGroup, String threadName) {
		super(threadGroup, threadName);
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				System.out.println(getName()+" interrupted");
				break;
			}
		}
		System.out.println(getName()+ " ์ข…๋ฃŒ๋จ");
	}
}

public class Main{
	public static void main(String[] args) {
		ThreadGroup myGroup = new ThreadGroup("myGroup");
		WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
		WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
		
		workThreadA.start();
		workThreadB.start();
		
		System.out.println("[main ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ list() ๋ฉ”์†Œ๋“œ ์ถœ๋ ฅ ๋‚ด์šฉ]");
		ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); //ํ˜„์žฌ์“ฐ๋ ˆ๋“œ์˜ ๊ทธ๋ฃน
		mainGroup.list();
		
		System.out.println();
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {}
		
		System.out.println("[myGroup ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ interrupted() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ]");
		myGroup.interrupt();
	}
}

- WorkThread ํด๋ž˜์Šค๋ฅผ ๋ณด๋ฉด catch๋ฌธ์œผ๋กœ interrupt ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€ ๋ชจ์Šต์ด๋‹ค. while๋ฌธ์„ ๋Œ๋ฉด์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด ํƒˆ์ถœํ•œ๋‹ค.

- list ๋ฉ”์†Œ๋“œ๋Š” ํ˜„์žฌ ๊ทธ๋ฃน์˜ ์ด๋ฆ„๊ณผ ์ตœ๋Œ€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ํ—ค๋”๋กœ ์ถœ๋ ฅํ•˜๊ณ  ๊ทธ์•„๋ž˜ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ์“ฐ๋ ˆ๋“œ์™€ ํ•˜์œ„ ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ค€๋‹ค.

- ๋งจ ์•„๋ž˜์ชฝ์˜ myGroup.interrupt() ๋ฉ”์†Œ๋“œ๋Š” ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์— ํฌํ•จ๋œ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ์— interrupt() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

- ์‹คํ–‰๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒํ•œ ๋’ค ๋‘๊ฐœ์˜ WorkThread ๊ฐ์ฒด ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

[main ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ list() ๋ฉ”์†Œ๋“œ ์ถœ๋ ฅ ๋‚ด์šฉ]
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=myGroup,maxpri=10]
        Thread[workThreadA,5,myGroup]
        Thread[workThreadB,5,myGroup]

[myGroup ์“ฐ๋ ˆ๋“œ ๊ทธ๋ฃน์˜ interrupted() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ]
workThreadA interrupted
workThreadA ์ข…๋ฃŒ๋จ
workThreadB interrupted
workThreadB ์ข…๋ฃŒ๋จ


์“ฐ๋ ˆ๋“œ ํ’€ ์˜ˆ์ œ , ๊ฐœ๋… (Future ๊ฐ์ฒด, execute(), submit())

์“ฐ๋ ˆ๋“œํ’€

- ๋ณ‘๋ ฌ์ž‘์—… ์ฒ˜๋ฆฌ๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์“ฐ๋ ˆ๋“œ ๊ฐœ์ˆ˜ ์ฆ๊ฐ€ -> ์“ฐ๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ์Šค์ผ€์ฅด๋ง์„ CPU๊ฐ€ ๋ฐ”๋น ์ ธ์„œ ๋ฉ”๋ชจ๋ฆฌ ๋งŽ์ด ์‚ฌ์šฉ

- ๊ฒฐ๊ตญ ์„ฑ๋Šฅ์ €ํ•˜.

- ๊ฐ‘์ž‘์Šค๋Ÿฐ ๋ณ‘๋ ฌ ์ž‘์—…์ฒ˜๋ฆฌ๊ฐ€ ๋งŽ์•„์งˆ ๋•Œ ์“ฐ๋ ˆ๋“œํ’€์„ ์ด์šฉ.

- ์“ฐ๋ ˆ๋“œ๋ฅผ ์ œํ•œ๋œ ๊ฐœ์ˆ˜๋งŒํผ ์ •ํ•ด๋†“๊ณ  ์ž‘์—…ํ(Queue)์— ๋“ค์–ด์˜ค๋Š” ์ž‘์—…๋“ค์„ ํ•˜๋‚˜์”ฉ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋งก์•„์„œ ์ฒ˜๋ฆฌ.

- ์“ฐ๋ ˆ๋“œํ’€ ์ƒ์„ฑ/์‚ฌ์šฉ์„ ์œ„ํ•ด Executors ํด๋ž˜์Šค์™€ ExecutorService ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณต.

- Executors์˜ ๋‹ค์–‘ํ•œ ์ •์ ๋ฉ”์†Œ๋“œ๋กœ ExecutorService์˜ ๊ตฌํ˜„๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์“ฐ๋ ˆ๋“œํ’€.

์“ฐ๋ ˆ๋“œํ’€ ์ƒ์„ฑ

Executors ํด๋ž˜์Šค

- newCachedThreadPool()

- newFixedThreadPool()

ExecutorService executorService = Executors.newCachedThreadPool();

ExecutorService executorService2 = Executors.newFixedThreadPool(
	Runtime.getRuntime().availableProcessors();
); //cpu์˜ ์ฝ”์–ด์ˆ˜๋งŒํผ ์ตœ๋Œ€์“ฐ๋ ˆ๋“œํ’€ ์ƒ์„ฑ
์“ฐ๋ ˆ๋“œํ’€ ์ข…๋ฃŒ

executorService.shutdown() - ๋‚จ์•„์žˆ๋Š” ์ž‘์—…์„ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ์“ฐ๋ ˆ๋“œํ’€ ์ข…๋ฃŒ

executorService.shutdownNow() - ๋‚จ์•„์žˆ๋Š” ์ž‘์—…๊ณผ๋Š” ์ƒ๊ด€์—†์ด ๊ฐ•์ œ๋กœ ์ข…๋ฃŒ

์ž‘์—…์ƒ์„ฑ๊ณผ ์ฒ˜๋ฆฌ์š”์ฒญ

์ž‘์—…์ƒ์„ฑ

- ํ•˜๋‚˜์˜ ์ž‘์—…์€ Runnable or Callable ๊ตฌํ˜„ ํด๋ž˜์Šค๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

- Runnable(๋ฌด)๊ณผ Callable(์œ )์˜ ์ฐจ์ด๋Š” ๋ฆฌํ„ด๊ฐ’์˜ ์œ ๋ฌด์ด๋‹ค.

Runnable task = new Runnable(){
	@Override
    public void run(){ /*์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ž‘์—… ๋‚ด์šฉ*/ }
}

Callable<T> taskc = new Callable<T>(){
	@Override
    public T call() throws Exception{
    	//์“ฐ๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ž‘์—… ๋‚ด์šฉ
		return T;
    }
}
์ž‘์—…์ฒ˜๋ฆฌ์š”์ฒญ

- ExecutorService์˜ ์ž‘์—…ํ์— Runnable ํ˜น์€ Callable๊ฐ์ฒด๋ฅผ ๋„ฃ๋Š” ํ–‰์œ„

- ์ž‘์—…์ฒ˜๋ฆฌ ์š”์ฒญ์„ ์œ„ํ•ด submit()๊ณผ execute() ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•จ.

- execute() : Runnable์„ ์ž‘์—…ํ์— ์ €์žฅ

- submit() : Runnable ๋˜๋Š” Callable์„ ์ž‘์—…ํ์— ์ €์žฅ, Future ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ด

- submit ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์“ฐ๋ ˆ๋“œ์˜ ์ƒ์„ฑ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๋Š”๋ฐ ์ข‹๋‹ค. ์™œ๋ƒํ•˜๋ฉด execute๋ฉ”์†Œ๋“œ๋Š” ์ž‘์—…์ฒ˜๋ฆฌ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์“ฐ๋˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ํ•˜์ง€๋งŒ submit ๋ฉ”์†Œ๋“œ๋Š” ์“ฐ๋˜ ์“ฐ๋ ˆ๋“œ๋ฅผ ์žฌํ™œ์šฉํ•œ๋‹ค.

(์ด๋Š” ์“ฐ๋ ˆ๋“œ์ด๋ฆ„์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.)

public static void main(String[] args) throws Exception{
		ExecutorService executorService = Executors.newFixedThreadPool(2); //์ตœ๋Œ€์“ฐ๋ ˆ๋“œ ๊ฐœ์ˆ˜๊ฐ€ 2์ธ ์“ฐ๋ ˆ๋“œํ’€ ์ƒ์„ฑ
		
		for(int i =0; i<10; i++) {
			Runnable runnable = new Runnable() {

				@Override
				public void run() {
					ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
					int poolSize = threadPoolExecutor.getPoolSize();
					String threadName = Thread.currentThread().getName();
					System.out.println("[์ด ์“ฐ๋ ˆ๋“œ ๊ฐœ์ˆ˜ : "+poolSize+"] ์ž‘์—… ์“ฐ๋ ˆ๋“œ ์ด๋ฆ„ :"+threadName);
					
					//์˜ˆ์™ธ ๋ฐœ์ƒ์‹œํ‚ด
					int value = Integer.parseInt("์‚ผ");
				}
			};	
            //์ด ๋‘๊ฐœ๋ฅผ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰ํ•ด๋ณด์„ธ์š”.
			//executorService.execute(runnable);
			executorService.submit(runnable);
			
			Thread.sleep(10);//์ฝ˜์†” ์ถœ๋ ฅ์‹œ๊ฐ„์„ ์œ„ํ•ด 0.01์ดˆ ์ผ์‹œ์ •์ง€
		}
		executorService.shutdown();
	}