[Java] Thread ๐Ÿฆ„๐Ÿฆ“

soyeonยท2022๋…„ 7์›” 14์ผ
0
post-thumbnail

์ค‘์š”ํ•œ ์šฉ์–ด, class, method

Process

: ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ
: resource + thread(์—ฌ๋Ÿฌ๊ฐœ)

์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” OS๋กœ๋ถ€ํ„ฐ resource๋ฅผ ํ• ๋‹น ๋ฐ›์•„์•ผ ํ•œ๋‹ค. ํ• ๋‹น ๋ฐ›์•„์„œ ์‹คํ–‰ํ•œ ํ”„๋กœ๊ทธ๋žจ์„ process๋ผ๊ณ  ํ•œ๋‹ค.

process์—๋Š” ์ตœ์†Œ ํ•œ ๊ฐœ ์ด์ƒ์˜ thread๊ฐ€ ์กด์žฌํ•œ๋‹ค.
thread๊ฐ€ ๋”ฑ ํ•œ ๊ฐœ ์žˆ๋Š” ๊ฒฝ์šฐ : single-thread process
thread๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ ์žˆ๋Š” ๊ฒฝ์šฐ : multi-thread process
-> ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ–ˆ๋˜ ํ”„๋กœ๊ทธ๋žจ(์ฝ”๋“œ)๋“ค ์•ˆ์—๋Š” thread๊ฐ€ ํ•˜๋‚˜์ด๋‹ค. ์ฝ”๋“œ์—์„œ thread๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

resource
1. code : ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ฝ”๋“œ
2. data : ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ
3. Heap : ๋™์  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ
4. Stack : ํ•จ์ˆ˜ ์Šคํƒ ์˜์—ญ

process์˜ ์ข…๋ฃŒ

: ๋‚ด๋ถ€์—์„œ ํŒŒ์ƒ๋œ ๋ชจ๋“  User define thread๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” ์ˆœ๊ฐ„ ์ข…๋ฃŒ๋œ๋‹ค.

CPU (core)

: 1๊ฐœ์˜ core๋Š” ํ•œ ์ˆœ๊ฐ„์— ํ•œ๊ฐ€์ง€ ์ผ๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ, Single Core์ธ ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ •ํ•˜๋ฉด
์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ์ด ๋งˆ์น˜ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.
ex) Excel, powerpoint, game, music, ...
-> time slicing (์‹œ๋ถ„ํ• ) ๊ธฐ๋ฒ•
-> Multitasking (core์˜ ๊ฐœ์ˆ˜์™€๋Š” ์ƒ๊ด€ ์—†๋‹ค.)

Multiprocessing
: ํ”„๋กœ๊ทธ๋žจ ๋‘๊ฐœ๊ฐ€ ์‹œ๊ฐ„์ ์œผ๋กœ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ
core๊ฐ€ ํ•œ ๊ฐœ์ด๋ฉด ์•ˆ๋œ๋‹ค. ์—ฌ๋Ÿฌ๊ฐœ์˜ core์—ฌ์•ผ ํ•œ๋‹ค.

Thread

: execution stack์„ ๋ณ„๋„๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‹คํ–‰ ํ๋ฆ„

stack์€ thread ๋ณ„๋กœ ํ• ๋‹น์ด ๋œ๋‹ค. main๋„ ํ•˜๋‚˜์˜ ์‹คํ–‰ ํ๋ฆ„(thread)์ด๋‹ค. -> main thread

thread

ํ”„๋กœ๊ทธ๋žจ ์•ˆ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ thread๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์‹คํ–‰ํ๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์ž‘์—…์„ ๋‚˜๋ˆ„์–ด์„œ ๋™์‹œ์— ์ˆ˜ํ–‰ ํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ด๋‹ค.

thread๊ฐ€ ๋ฌด์กฐ๊ฑด ๋งŽ์„์ˆ˜๋ก ์ข‹์ง€๋Š” ์•Š๋‹ค.
stack ์˜์—ญ์ด thread๋งˆ๋‹ค ํ• ๋‹น์ด ๋˜์–ด์•ผ ํ•˜๋‹ˆ๊นŒ resource๊ฐ€ ๋ถ€์กฑํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
-> ์ ์ •์–‘์˜ thread๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

Multi-threading

: ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ thread๊ฐ€ ์กด์žฌํ•  ๋•Œ, ์‹œ๊ฐ„์ƒ ๋™์‹œ์— ์‹คํ–‰์ด ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•˜๋Š” ๊ฒƒ
time slicing(์‹œ๋ถ„ํ• )๋กœ multitasking์ด ์ผ์–ด๋‚˜๊ฑฐ๋‚˜
์—ฌ๋Ÿฌ๊ฐœ์˜ core๋กœ multiprocessing์ด ์ผ์–ด๋‚  ์ˆ˜๋„ ์žˆ๋‹ค.

์žฅ์ 

  • ํšจ์œจ์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์‘๋‹ต์†๋„๊ฐ€ ์ข‹์•„์ง„๋‹ค.

๋‹จ์ 

  • ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋ ต๋‹ค.
  • ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ "๋™๊ธฐํ™” ์ฒ˜๋ฆฌ"๊ฐ€ ์–ด๋ ต๋‹ค. -> ์ด๋กœ ์ธํ•œ ๊ต์ฐฉ๋ฌธ์ œ(deadlock)
  • ์ œ์–ด๊ฐ€ ๊นŒ๋‹ค๋กญ๋‹ค.

os๊ทธ๋ฆผ

Java์—์„œ Thread ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ ค๋ฉด?

thread ์ƒ์„ฑ

main thread

thread๋ฅผ ๋งŒ๋“ค ๋•Œ, JVM์ด thread๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ thread๊ฐ€ main์„ ํ˜ธ์ถœํ•œ๋‹ค. ์ด thread๋ฅผ main thread๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Java์—์„œ thread๋Š” instance์ด๋‹ค. -> ์ด instance๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” class๊ฐ€ ์กด์žฌํ•œ๋‹ค.
=> Thread class

  1. Thread class๋ฅผ ์ƒ์†ํ•ด์„œ User define thread class๋ฅผ ์ด์šฉํ•œ๋‹ค.
    -> ์ž˜ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. Java๋Š” ๋‹ค์ค‘ ์ƒ์†์ด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์— thread class๋ฅผ ์ƒ์†ํ•˜๋ฉด ๋‹ค๋ฅธ class๋ฅผ ์ƒ์† ๋ฐ›์„ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. class๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์ƒ์†๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋ฉด tightly coupled ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ด ์žฌ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.
  2. Runnable interface๋ฅผ ๊ตฌํ˜„ํ•ด์„œ User define class๋ฅผ ๋งŒ๋“ค๊ณ , ์ด class์˜ instance๋ฅผ ๋งŒ๋“ ๋‹ค.
    -> ๋งŒ๋“  instance๋ฅผ new Thread()์˜ ์ธ์ž๋กœ ๋„ฃ์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

์ฝ”๋“œ๋กœ ์•Œ์•„๋ณด๊ธฐ

  1. Thread class ์ƒ์†ํ•ด์„œ ์ƒ์„ฑ
  • ์ƒˆ๋กœ์šด thread๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ
package lecture0714;

class MyThread extends Thread{
	
	@Override
	public void run() {
		System.out.println("Hello");
	}
}

public class Main {
	public static void main(String[] args) {
		
		MyThread t = new MyThread();
		t.run();
	}
}

  1. main์ด ์‹œ์ž‘ํ•˜๋ฉด call stack์— main์ด ์Œ“์ธ๋‹ค.
  2. MyThread์˜ instance๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.
  3. t.run()์„ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋ฉด call stack์— ์Œ“์ด๊ณ , ์ƒˆ๋กœ์šด ์‹คํ–‰ ํ๋ฆ„์ด ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.
  • ์ƒˆ๋กœ์šด thread๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์ฝ”๋“œ
package lecture0714;

class MyThread extends Thread{
	
	@Override
	public void run() {
		System.out.println("Hello");
	}
}

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

start()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ์ƒˆ๋กœ์šด thread / ์‹คํ–‰ ํ๋ฆ„์ด ์ƒ๊ฒจ๋‚˜๊ฒŒ ๋œ๋‹ค.

start()
: thread ์ƒ์„ฑ, stack ํ• ๋‹น, run() ํ˜ธ์ถœ

  1. Runnable interface๋กœ ์ƒ์„ฑ
  • ์ƒˆ๋กœ์šด thread ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ
package lecture0714;

class MyThread2 implements Runnable {

	@Override
	public void run() {
		System.out.println("์ด๊ฒƒ๋„ ์‹คํ–‰!");
	}
}

public class Main {
	public static void main(String[] args) {

		MyThread2 a = new MyThread2();  // ์•„์ง thread๊ฐ€ ์•„๋‹ˆ๋‹ค.
		Thread t1 = new Thread(a);
		t1.start();
		
		System.out.println("์•ˆ๋…•ํ•˜์„ธ์š”!");
	}
}

thread ์—ฐ์Šต ์ฝ”๋“œ

package lecture0714;

class ThreadEx_01_1 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<5; i++) {
			System.out.println(getName());
		}
	}
}

class ThreadEx_01_2 implements Runnable {
	
	@Override
	public void run() {
		for(int i=0; i<5; i++) {
			System.out.println(Thread.currentThread().getName());  // Thread class์˜ static method. ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” thread๋ฅผ ์ง€์นญํ•œ๋‹ค.
		}
	}
}

public class ThreadExam01 {
	
	public static void main(String[] args) {
		
		ThreadEx_01_1 t1 = new ThreadEx_01_1();
		
		ThreadEx_01_2 r = new ThreadEx_01_2();
		Thread t2 = new Thread(r);
		
		// ์…‹ ์ค‘์—์„œ ์–ด๋–ค ๊ฒƒ์ด ๋จผ์ € ์‹คํ–‰๋ ์ง€๋Š” ๋ชจ๋ฅธ๋‹ค.
		// ์Šค์ผ€์ค„๋Ÿฌ์— ์˜ํ•ด์„œ ์„ ํƒ๋˜์–ด์„œ ์‹คํ–‰๋œ๋‹ค.
		t1.start();
		t2.start();		
		System.out.println("main thread ์ข…๋ฃŒ");
	}
}

Thread์˜ ์ƒํƒœ์ „์ด๋„

thread์˜ ์ƒํƒœ์ „์ด๋„

Single core & Multi core

single thread์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์ž‘์—…์ด ๋‘๊ฐœ์ด๋‹ค. (A,B)

  • single core์—์„œ thread ํ•œ ๊ฐœ ์ผ๋•Œ
  • single core์—์„œ thread ๋‘ ๊ฐœ ์ผ๋•Œ

    => A์™€ B๊ฐ€ ๋‘˜ ๋‹ค ๋๋‚˜๋Š” ์‹œ์ ์€ ์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ด ๋” ๋น ๋ฅด๋‹ค.
    context switching ์ž‘์—…์ด ๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ด ๋” ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. multi core๊ฐ€ ์•„๋‹ˆ๋ฉด ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.
  • multi core์—์„œ thread ๋‘ ๊ฐœ ์ผ๋•Œ

    ๋นจ๋ฆฌ ๋๋‚  ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ์Šคํ…œ์€ multi core๋กœ ๋˜์–ด ์žˆ๋‹ค.

thread ์šฐ์„ ์ˆœ์œ„

: setPriority()
single core์—์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. multi core์—์„œ๋Š” ์˜๋ฏธ๊ฐ€ ์—†๋‹ค. ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

Daemon Thread (๋ฐ๋ชฌ Thread)

: ๋‹ค๋ฅธ ์ผ๋ฐ˜ thread์˜ ๋ณด์กฐ์ ์ธ ์ž‘์—…์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
ํ•ด๋‹น daemon thread๋ฅผ ํŒŒ์ƒ์‹œํ‚จ thread๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๊ฐ™์ด ์ข…๋ฃŒ๋œ๋‹ค.
ex) Garbage collecttion, ์ž๋™ ์ €์žฅ ๊ธฐ๋Šฅ

t1.setDaemon(true);

์—ฐ์Šต ์ฝ”๋“œ

package lecture0714;

// Daemon Thread ์•Œ์•„๋ณด๊ธฐ
public class ThreadExam02 implements Runnable {
	
	static boolean autoSave = false;
	
	public static void main(String[] args) {
		Thread t = new Thread(new ThreadExam02());
		
		t.setDaemon(true);
		
		t.start();
		
		for(int i=0; i<10; i++) {
			try {
				Thread.sleep(1000);  // main thread๋ฅผ ์žฌ์šด๋‹ค.
			} catch (Exception e) {
				
			}
			System.out.println(i);
			
			if(i == 5) {
				autoSave = true;
			}
		}
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3000);  // t thread๋ฅผ ์žฌ์šด๋‹ค.
			} catch (InterruptedException e) {
				
			}
			
			if(autoSave) {
				System.out.println("์ž๋™์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!");
			}
		}
	}
}

๊ธฐ์–ตํ•ด์•ผ ํ•˜๋Š” thread์˜ method

sleep(long millisecond)

: ์ผ์ • ์‹œ๊ฐ„๋™์•ˆ thread๋ฅผ ์ค‘์ง€์‹œํ‚จ๋‹ค.

sleep์— ๋“ค์–ด๊ฐ€๋ฉด ์ฟจ์ฟจ ์ž”๋‹ค. sleep์—์„œ ๊นจ์–ด๋‚˜๋Š” ์กฐ๊ฑด
1. ์ง€์ •๋œ ์‹œ๊ฐ„์ด ๋‹ค ๋˜์—ˆ๋‹ค.
2. Thread์— ๋Œ€ํ•ด interrupt()๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. (InterruptedExceiption์ด ๋ฐœ์ƒ)
-> ์ด ์ด์œ  ๋•Œ๋ฌธ์— sleep์€ ํ•ญ์ƒ try~catch ๋ฌธ๊ณผ ํ•จ๊ป˜ ์“ฐ์—ฌ์•ผ ํ•œ๋‹ค.

sleep ์ƒํƒœ ์ „์ด๋„

sleep ์ƒํƒœ ์ „์ด๋„
: sleep์—์„œ ๊นจ์–ด๋‚˜๋Š” ์กฐ๊ฑด์ด ๋˜๋ฉด Running ์ƒํƒœ๋กœ ๊ฐ€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Runnable ์ƒํƒœ๋กœ ๋Œ์•„๊ฐ„๋‹ค. ๋‹ค์‹œ Runnable ์ƒํƒœ์˜ thread๋“ค๊ณผ ์„ ํƒ๋ฐ›๊ธฐ ์œ„ํ•ด ๊ฒฝ์Ÿํ•œ๋‹ค.

sleep ์ฃผ์˜ํ•ด์•ผ ํ•  ์ฝ”๋“œ

package lecture0714;

class ThreadEx_03_1 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.print("-");
		}
		System.out.println("<<Thread 1 ์ข…๋ฃŒ>>");
	}
}

class ThreadEx_03_2 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.print("|");
		}
		System.out.println("<<Thread 2 ์ข…๋ฃŒ>>");
	}
}

public class ThreadExam03 {
	
	public static void main(String[] args) {
		
		ThreadEx_03_1 t1 = new ThreadEx_03_1();
		ThreadEx_03_2 t2 = new ThreadEx_03_2();
		
		t1.start();
		t2.start();
		
		try {
			t1.sleep(2000);  // ํ˜„์žฌ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” thread๋ฅผ ์žฌ์šฐ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— main thread๊ฐ€ ์ž”๋‹ค.
			// t1.sleep(2000) ์ด๋‚˜ t2.sleep(2000) ์ด๋‚˜ Thread.sleep(2000) ์ด๋‚˜ ๋ชจ๋‘ ๊ฐ™๋‹ค.
		} catch (Exception e) {
			
		}
		System.out.println("<<main Thread ์ข…๋ฃŒ>>");
	}
}
  • ํ•ด๊ฒฐ ์ฝ”๋“œ
    sleep ์‹œํ‚ค๋ ค๋Š” thread ์ฝ”๋“œ์— sleep์„ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
package lecture0714;

class ThreadEx_03_1 extends Thread {
	
	@Override
	public void run() {		
		try {
			Thread.sleep(2000);
		} catch (Exception e) {
			
		}
		
		for(int i=0; i<300; i++) {
			System.out.print("-");
		}
		System.out.println("<<Thread 1 ์ข…๋ฃŒ>>");
	}
}

class ThreadEx_03_2 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.print("|");
		}
		System.out.println("<<Thread 2 ์ข…๋ฃŒ>>");
	}
}

public class ThreadExam03 {
	
	public static void main(String[] args) {
		
		ThreadEx_03_1 t1 = new ThreadEx_03_1();
		ThreadEx_03_2 t2 = new ThreadEx_03_2();
		
		t1.start();
		t2.start();
		
		System.out.println("<<main Thread ์ข…๋ฃŒ>>");
	}
}

interrupt()

: Thread ์‹คํ–‰ ํ›„ ์ž‘์—…์ด ๋๋‚˜๊ธฐ ์ „์— ํ•ด๋‹น thread๋ฅผ ์ค‘์ง€์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

interrupt()๋Š” ์ง์ ‘ ์ค‘์ง€ ์‹œํ‚ค์ง€ ์•Š๊ณ , thread์˜ ๋‚ด๋ถ€์ƒํƒœ ๊ฐ’์ธ "Interrupted state"๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

๐ŸคกThread๊ฐ€ interrupt๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” method

  1. interrupted() - Thread class์˜ static
    : ํ˜„์žฌ ์ˆ˜ํ–‰ ์ค‘์ธ thread๊ฐ€ interrupt๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ์•„๋‚ธ๋‹ค.
    interrupt ์—ฌ๋ถ€๋ฅผ ์กฐ์‚ฌํ•˜๊ณ  ์ƒํƒœ๊ฐ’์„ ๋ฌด์กฐ๊ฑด False๋กœ ๋ฐ”๊พผ๋‹ค.

  2. isInterrupted() - Thread class์˜ static X
    : ํŠน์ • thread๊ฐ€ interrupt๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ์•„๋‚ธ๋‹ค.
    interrupt ์—ฌ๋ถ€๋ฅผ ์กฐ์‚ฌ๋งŒ ํ•˜๊ณ  ์ƒํƒœ๊ฐ’๋งŒ ๋ฆฌํ„ดํ•œ๋‹ค.(True/False)

stop() - thread์˜ ๊ฐ•์ œ ์ค‘์ง€
-> ์˜๋„์น˜ ์•Š์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด ํ˜„์žฌ๋Š” ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. (deprecated)
suspend() - thread์˜ ์ผ์‹œ ์ค‘์ง€
resume() - ์ผ์‹œ ์ค‘์ง€๋œ thread์˜ ์žฌ์‹œ์ž‘
start() - thread์˜ ์‹œ์ž‘

  • ์ฝ”๋“œ
    : deprecated ๋œ ๊ฒƒ ์‚ฌ์šฉ
package lecture0714;

class ThreadEx_05 implements Runnable {

	@Override
	public void run() {
		while(true) {  // 1์ดˆ ์žค๋‹ค ์ผ์–ด๋‚˜์„œ ์ž์‹ ์˜ ์ด๋ฆ„์„ ์ฐ๋Š”๋‹ค.
			System.out.println(Thread.currentThread().getName());
			
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
				
			}
		}
	}
}

public class ThreadExam05 {
	
	public static void main(String[] args) {
		
		ThreadEx_05 r = new ThreadEx_05();
		Thread t1 = new Thread(r, "*");  // thread์˜ ์ด๋ฆ„์„ *๋กœ ์ง“๋Š”๋‹ค.
		Thread t2 = new Thread(r, "**");
		Thread t3 = new Thread(r, "***");
		
		t1.start();
		t2.start();
		t3.start();
		
		try {
			Thread.sleep(2000);  // main thread ์žฌ์šฐ๊ธฐ
			t1.suspend();  // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			t2.suspend();
			Thread.sleep(2000);
			t1.resume();  // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			t1.stop();
			t2.stop();
			Thread.sleep(2000);
			t3.stop();
		} catch (Exception e) {

		}
	}
}

: no deprecated ์‚ฌ์šฉ

package lecture0714;

class ThreadEx_06 implements Runnable {

	volatile boolean suspended = false;
	volatile boolean stopped = false;
	
	@Override
	public void run() {
		while(!stopped) {  // 1์ดˆ ์žค๋‹ค ์ผ์–ด๋‚˜์„œ ์ž์‹ ์˜ ์ด๋ฆ„์„ ์ฐ๋Š”๋‹ค.
			if(!suspended) {
				System.out.println(Thread.currentThread().getName());
				
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					
				}
			}
		}
	}
	
	public void suspend() {
		suspended = true;
	}
	
	public void stop() {
		stopped = true;
	}
	
	public void resume() {
		suspended = false;
	}
}

public class ThreadExam06 {

	public static void main(String[] args) {
		
		ThreadEx_06 r1 = new ThreadEx_06();
		ThreadEx_06 r2 = new ThreadEx_06();
		ThreadEx_06 r3 = new ThreadEx_06();
		
		Thread t1 = new Thread(r1, "*");  // thread์˜ ์ด๋ฆ„์„ *๋กœ ์ง“๋Š”๋‹ค.
		Thread t2 = new Thread(r2, "**");
		Thread t3 = new Thread(r3, "***");
		
		t1.start();
		t2.start();
		t3.start();
		
		try {
			Thread.sleep(2000);  // main thread ์žฌ์šฐ๊ธฐ
			r1.suspend();  // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r2.suspend();
			Thread.sleep(2000);
			r1.resume();  // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			r1.stop();
			r2.stop();
			Thread.sleep(2000);
			r3.stop();
		} catch (Exception e) {

		}	
	}
}

volatile์ด ์—†์„ ๋•Œ๋Š” ์ œ๋Œ€๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ์—์„œ๋Š” ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด ํ•„๋“œ๊ฐ’์„ ๋ฐ”๊พธ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋Œ€๋กœ ์ž‘๋™๋˜์ง€ ์•Š์•˜๋‹ค. volatile์„ ๋ถ™์—ฌ์„œ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ฒŒ ๋ฐ”๊ฟ”์ค€๋‹ค.
volatile

interrupt ์˜ˆ์ œ ์ฝ”๋“œ

package lecture0714;

import javax.swing.JOptionPane;

class ThreadEx_04 extends Thread {
	
	@Override
	public void run() {
		int i = 10;
		
		while(i != 0 && !isInterrupted()) {  // i๊ฐ€ 0์ด ์•„๋‹ˆ๊ณ , interrupt๊ฐ€ ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜์œผ๋ฉด ๊ณ„์† ๋ฐ˜๋ณตํ•œ๋‹ค.
			System.out.println(--i);
			
			try {
				Thread.sleep(4000);
				// sleep์—์„œ interrupt๊ฐ€ ๊ฑธ๋ฆฌ๋ฉด interrupted ์ƒํƒœ๊ฐ€ ๋‹ค์‹œ false๊ฐ€ ๋œ๋‹ค.
			} catch (Exception e) {
				interrupt();
			}
			// for(long k=0; i<2500000000L; k++);  // ์‹œ๊ฐ„ ์ง€์—ฐ
		}
		System.out.println("์นด์šดํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์–ด์š”!");
	}
}

public class ThreadExam04 {
	
	public static void main(String[] args) {
		
		Thread t = new ThreadEx_04();
		
		t.start();
		
		String input = JOptionPane.showInputDialog("๊ฐ’์„ ์ž…๋ ฅํ•˜์„ธ์š”!");  // ๊ฐ’์„ ์ž…๋ ฅํ•  ๋•Œ๊นŒ์ง€ main thread๋Š” ์—ฌ๊ธฐ์„œ blocking ๋œ๋‹ค.
		System.out.println("์ž…๋ ฅ๊ฐ’์€ : " + input);
		
		t.interrupt();  
		// thread t์˜ ๋‚ด๋ถ€์ƒํƒœ ์ •๋ณด(interrupted ์ƒํƒœ)๋ฅผ true๋กœ ๋ฐ”๊พผ๋‹ค.
		
		System.out.println("Thread ์ƒํƒœ๊ฐ’์€ : " + t.isInterrupted());
	}
}

yield()

: Thread๊ฐ€ ์ž์‹ ์—๊ฒŒ ์ฃผ์–ด์ง„ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋‹ค ์“ฐ์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ thread์—๊ฒŒ ์–‘๋ณดํ•œ๋‹ค.
-> ํ”„๋กœ๊ทธ๋žจ์˜ ์‘๋‹ต์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

yield ์ƒํƒœ ์ „์ด๋„

yield ์ƒํƒœ ์ „์ด๋„

yield ์˜ˆ์ œ ์ฝ”๋“œ

์œ„์˜ no deprecated ์˜ˆ์ œ์—์„œ๋Š” suspend๊ฐ€ ๋œ ์ƒํƒœ๋ผ๋ฉด ์ถœ๋ ฅ๋งŒ ๋˜์ง€ ์•Š๊ณ  while๋ฌธ์€ ๊ณ„์†ํ•ด์„œ ๋Œ๊ฒŒ ๋œ๋‹ค -> busy waiting
=> yeild๋กœ ๋‹ค๋ฅธ thread์—๊ฒŒ ์–‘๋ณดํ•œ๋‹ค.

package lecture0714;

class ThreadEx_06 implements Runnable {

	volatile boolean suspended = false;
	volatile boolean stopped = false;
	
	@Override
	public void run() {
		while(!stopped) {  // 1์ดˆ ์žค๋‹ค ์ผ์–ด๋‚˜์„œ ์ž์‹ ์˜ ์ด๋ฆ„์„ ์ฐ๋Š”๋‹ค.
			if(!suspended) {
				System.out.println(Thread.currentThread().getName());
				
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					
				}
			} else {
				Thread.yield();  // ์ผ์‹œ์ •์ง€๋ผ์„œ runnable ์ƒํƒœ๋กœ ๋ฐ”๋€Œ๋ฉด์„œ ๋น ์ง„๋‹ค.
			}
		}
	}
	
	public void suspend() {
		suspended = true;
	}
	
	public void stop() {
		stopped = true;
	}
	
	public void resume() {
		suspended = false;
	}
}

public class ThreadExam06 {

	public static void main(String[] args) {
		
		ThreadEx_06 r1 = new ThreadEx_06();
		ThreadEx_06 r2 = new ThreadEx_06();
		ThreadEx_06 r3 = new ThreadEx_06();
		
		Thread t1 = new Thread(r1, "*");  // thread์˜ ์ด๋ฆ„์„ *๋กœ ์ง“๋Š”๋‹ค.
		Thread t2 = new Thread(r2, "**");
		Thread t3 = new Thread(r3, "***");
		
		t1.start();
		t2.start();
		t3.start();
		
		try {
			Thread.sleep(2000);  // main thread ์žฌ์šฐ๊ธฐ
			r1.suspend();  // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r2.suspend();
			Thread.sleep(2000);
			r1.resume();  // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			r1.stop();
			r2.stop();
			Thread.sleep(2000);
			r3.stop();
		} catch (Exception e) {

		}	
	}
}

join()

: ๋‹ค๋ฅธ thread๋ฅผ ์ง€์ •ํ•ด์„œ ๋‚ด๊ฐ€ ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ๋Š” ์ค‘๊ฐ„์— ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
static method๊ฐ€ ์•„๋‹ˆ๋‹ค.

  • join()
    : ํ˜„์žฌ ์‹คํ–‰ ๋˜๊ณ  ์žˆ๋Š” thread๋ฅผ ์ผ์‹œ์ ์œผ๋กœ block ์‹œํ‚จ๋‹ค.
  • join(long ์ดˆ)

sleep์€ ํŠน์ • thread๋ฅผ ์ง€์ •ํ•ด์„œ ์žฌ์šธ ์ˆ˜๊ฐ€ ์—†๋‹ค. ํ˜„์žฌ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” thread๋ฅผ ์žฌ์šด๋‹ค. => ๊ทธ๋ž˜์„œ sleep์€ static method์ด๋‹ค.
ํ˜„์žฌ thread๊ฐ€ block ๋˜๋Š” ๊ฒƒ์€ join๊ณผ ๋™์ผํ•˜๋‹ค.

join ์ƒํƒœ ์ „์ด๋„

join ์ƒํƒœ ์ „์ด๋„

join ์˜ˆ์ œ ์ฝ”๋“œ

package lecture0715;

class ThreadEx_07_1 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.print("-");
		}
	}
}

class ThreadEx_07_2 extends Thread {
	
	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.print("|");
		}
	}
}

public class ThreadExam07 {
	
	public static void main(String[] args) {
		Thread t1 = new ThreadEx_07_1();
		Thread t2 = new ThreadEx_07_2();
		
		t1.start();
		t2.start();
		
		try {
			t1.join();  // main thread๋ฅผ ๋ฉˆ์ถ”๊ณ  t1์„ ํฌํ•จ์‹œํ‚จ๋‹ค.
			t2.join();
		} catch (Exception e) {
			// TODO: handle exception
		}
		System.out.println("<<main ์ข…๋ฃŒ>>");
	}
}
  • join์„ ์–ด๋””์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊นŒ?
package lecture0715;

class ThreadEx_08_1 extends Thread {
	
	final static int MAX_MEMORY = 1000;  // ์ตœ๋Œ€ ๋ฉ”๋ชจ๋ฆฌ ์šฉ๋Ÿ‰
	int usedMemory = 0;  // ์‚ฌ์šฉ๋œ ๋ฉ”๋ชจ๋ฆฌ๋Ÿ‰
	
	@Override
	public void run() {
		while(true) {  // ๋ฌดํ•œ ๋ฃจํ”„์ด๋ฉด ๋๋‚˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด thread๋Š” daemon thread๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค.
			try {
				Thread.sleep(10000);  // 10์ดˆ ๋™์•ˆ ์ž”๋‹ค.
			} catch (Exception e) {  // ์ž๋Š” ๋™์•ˆ ๋ˆ„๊ตฐ๊ฐ€ ๊นจ์›Œ์„œ interrupt ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ
				System.out.println("interrupt์— ์˜ํ•ด์„œ ๊นจ์–ด๋‚ฌ์–ด์š”!");
			}
			gc();
			System.out.println("๋ฉ”๋ชจ๋ฆฌ ์ฒญ์†Œ ์™„๋ฃŒ! ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ๋Ÿ‰ : " + freeMemory());
		}
	}
	
	// garbage collection
	private void gc() {  // ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” private์œผ๋กœ ์žก๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
		usedMemory -= 300;
		if(usedMemory < 0) {
			usedMemory = 0;
		}
	}
	
	public int totalMemory() { return MAX_MEMORY; }	
	public int freeMemory() { return MAX_MEMORY - usedMemory; }
}

public class ThreadExam08 {

	public static void main(String[] args) {
		
		ThreadEx_08_1 t = new ThreadEx_08_1();
		t.setDaemon(true);
		t.start();
		
		int requiredMemory = 0;
		
		for(int i=0; i<20; i++) {
			requiredMemory = (int)(Math.random() * 10) * 20;  // 0๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฌ๊ณ  200๋ณด๋‹ค ์ž‘์€ ์ •์ˆ˜
			
			// ํ•„์š”ํ•œ memory๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–‘๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜
			// ํ˜„์žฌ ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ์–‘์˜ 60% ์ด์ƒ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„ ๋•Œ gc๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
			if(requiredMemory > t.freeMemory() || t.freeMemory() < t.totalMemory() * 0.4) {
				t.interrupt();  // ์—ฌ๊ธฐ์—์„œ๋Š” main thread๋Š” gc() ์‹คํ–‰์ด ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.
				try {
					t.join(100);  // ์ด ์ฝ”๋“œ๋กœ main์ด gc() ์‹คํ–‰์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋œ๋‹ค.
				} catch (Exception e) {
					
				}
			}
			t.usedMemory += requiredMemory;
			System.out.println("์‚ฌ์šฉ๋œ ๋ฉ”๋ชจ๋ฆฌ๋Ÿ‰ : " + t.usedMemory);
		}
	}
}

Math.random()
0.0๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฌ๊ณ  1.0๋ณด๋‹ค ์ž‘์€ ์‹ค์ˆ˜

0๊ฐœ์˜ ๋Œ“๊ธ€