[Java] Thread๐Ÿ˜ถ

jy9922ยท2022๋…„ 7์›” 14์ผ
0

Java

๋ชฉ๋ก ๋ณด๊ธฐ
6/13
post-thumbnail

Thread๐Ÿ˜ถ

์˜ค๋Š˜ ๋ฐฐ์šธ๊ฑฐ...๐Ÿ“
1. Thread๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€?
2. ์ค‘์š”ํ•œ ์šฉ์–ด, class์™€ method
3. Network Server๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ™œ์šฉ

Thread๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€?

Process

  • ์‹คํ–‰์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ
  • ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด OS๋กœ๋ถ€ํ„ฐ resource๋ฅผ ํ• ๋‹น ๋ฐ›์•„์•ผ ํ•œ๋‹ค.
    • code (ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ฝ”๋“œ)
    • data (ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ)
    • heap
    • stack
  • process ๋‚ด์—๋Š” ์ตœ์†Œ 1๊ฐœ ์ด์ƒ์˜ thread๊ฐ€ ์กด์žฌํ•œ๋‹ค.
    • single-thread-process ( thread๊ฐ€ ๋”ฑ 1๊ฐœ ์กด์žฌ )
    • multi-thread-process ( thread๊ฐ€ 2๊ฐœ ์ด์ƒ ์กด์žฌ )
  • Process
    resource + thread ( ์ตœ์†Œ 1๊ฐœ ์ด์ƒ )

Thread

  • thread๋Š” excution stack์„ ๋ณ„๋„๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‹คํ–‰ ํ๋ฆ„์„ ๋งํ•œ๋‹ค.
  • ๋…๋ฆฝ์ ์ธ code๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์‹คํ–‰ ํ๋ฆ„์ด๊ธฐ ๋•Œ๋ฌธ์— thread๋งˆ๋‹ค ๋ณ„๋„์˜ stack์ด ํ• ๋‹น๋œ๋‹ค.
  • ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ์ฝ”๋“œ๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ•˜๋‚˜๊ฐ€ main ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์„ ๋™์ž‘์‹œ์ผฐ๋‹ค.
  • ์—ฌ๊ธฐ์„œ main์ด ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค์–ด ๋™์‹œ์— ์‹คํ–‰์‹œ์ผœ๋ณธ๋‹ค๋Š” ๊ฐœ๋…์ด ์ ์šฉ๋œ๋‹ค๋ฉด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ๋œ๋‹ค.
  • ๋‹จ์ผ ์Šค๋ ˆ๋“œ์™€ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ๋น„๊ตํ•ด๋ณด์•˜์„ ๋•Œ, ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ผ์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•˜๋Š” ์ธก๋ฉด์—์„œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ๋” ํšจ์œจ์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด, Thread๊ฐ€ ๋งŽ์„์ˆ˜๋ก ์ข‹์„๊นŒ?๐Ÿ™„

๊ทธ๋ ‡์ง€๋Š” ์•Š๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฐ๊ฐ์˜ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค stack ์˜์—ญ์ด ๋”ฐ๋กœ ํ• ๋‹น๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. thread๊ฐ€ ๋งŽ์œผ๋ฉด ๋งŽ์„์ˆ˜๋ก stack ์˜์—ญ์„ ์ชผ๊ฐœ์„œ ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด ์ ์—์„œ resource๊ฐ€ ๋ถ€์กฑํ•ด์ง€๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ ๋‹นํ•œ ์–‘์ด ์ข‹๋‹ค.

CPU (core)

core

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

time slicing

๋งŒ์•ฝ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ปดํ“จํ„ฐ๊ฐ€ single core๋ผ๋ฉด, core๋Š” ํ•˜๋‚˜์ธ๋ฐ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋งˆ์น˜ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ์–ด๋–ป๊ฒŒ..?

์‹œ๊ฐ„์„ ์ชผ๊ฐœ์„œ ๋งˆ์น˜ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Š” Multi tasking (core์˜ ๊ฐœ์ˆ˜์™€ ์ƒ๊ด€X) ์ด๋‹ค.

multi processing

์ง„์งœ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋™์‹œ์— ์‹คํ–‰, core๊ฐ€ 2๊ฐœ ์ด์ƒ์ผ๋•Œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

multi threading

ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ thread๊ฐ€ ์กด์žฌํ•  ๋•Œ, ์‹œ๊ฐ„์ƒ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Multi-threading

[์žฅ์ ]

  • ํšจ์œจ์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์‘๋‹ต์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค.

[๋‹จ์ ]

  • ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋ ต๋‹ค.
  • dead lock๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Java์—์„œ Thread๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ ค๋ฉด..์–ด๋–ป๊ฒŒ..?๐Ÿ˜ฎ

JVM์ด Thread๋ฅผ ์ƒ์„ฑ -> Thread๊ฐ€ main( ) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

  • ๋ฉ”์„œ๋“œ ์ž์ฒด๋ฅผ Thread์™€ ๋™์ผ์‹œํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
  • main( ) ๋ฉ”์„œ๋“œ๋Š” main thread์— ์˜ํ•ด์„œ ์‹คํ–‰๋œ๋‹ค.
  • Java์—์„œ์˜ thread๋Š” instance๋‹ค.
  • ํ•ด๋‹น instance๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” class๊ฐ€ ์กด์žฌํ•จ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ํ•ด๋‹น Thread๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” class๊ฐ€ ๋ฐ”๋กœ Thread class๋‹ค.

[Java๋กœ thread ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•]

[ ๋ฐฉ๋ฒ• 1 ]

  • Thread class๋ฅผ ์ƒ์†ํ•ด์„œ user-define thread class๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
    • ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค.
    • Java๋Š” ๋‹ค์ค‘์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ์— ์ œ์•ฝ์ด ์ƒ๊ธด๋‹ค.
    • ํด๋ž˜์Šค๋ผ๋ฆฌ tightly coupled ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์žฌ์‚ฌ์šฉ์— ์ œ์•ฝ์ด ์ƒ๊ธด๋‹ค.

[ ๋ฐฉ๋ฒ• 2 ]

  • Runable interface๋ฅผ ๊ตฌํ˜„ํ•ด์„œ user-define class๋ฅผ ๋งŒ๋“ ๋‹ค.
    • ์ด ํด๋ž˜์Šค๊ฐ€ Thread ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
  • user-define class์˜ instance๋ฅผ ๋งŒ๋“ ๋‹ค.
    • new Thread( )๋ฅผ ํ†ตํ•ด ํ• ๋‹นํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
    • ์œ„ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  Thread class์˜ ์ธ์ž๋กœ ๋„˜๊ธด๋‹ค.

[๋ฐฉ๋ฒ•1] ์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด๊ธฐ (์ƒ์†)

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(); // ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
		t.start(); // 1. thread ์ƒ์„ฑ 2. stack ํ˜ธ์ถœ 3. run()ํ˜ธ์ถœ
        
        System.out.println("์•ˆ๋…•ํ•˜์„ธ์š”!");
        // ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค.
	}
}

[๋ฐฉ๋ฒ•2] ์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด๊ธฐ (Runnable)

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

class MyThread2 implements Runnable{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("์ด๊ฒƒ๋„ ์‹คํ–‰๋˜์š”!");
	}
}
public class Main {
	
	public static void main(String[] args) {
		
		MyThread t = new MyThread();
//		t.run(); // ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
		t.start(); 
		
		MyThread2 a = new MyThread2();

		Thread t1 = new Thread(a); // Thread ๊ฐ์ฒด์— ์ธ์ž ๋„˜๊ธฐ๊ธฐ -> ์‹ค์ œ Thread ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ
		t1.start();
		
		System.out.println("์•ˆ๋…•ํ•˜์„ธ์š”!");
	}
}

t.start( );

  1. thread ์ƒ์„ฑ
  2. stack ํ˜ธ์ถœ
  3. run( ) ํ˜ธ์ถœ

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()); 
			// ์•„์ง ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹ˆ์—ฌ์„œ this.getName() ์‚ฌ์šฉ ๋ชปํ•จ.
			// ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” static ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
			// ์ด ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š”๋ฐ ํ˜„์žฌ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์ง€์นญํ•จ
		}
	}
}
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 ์ƒํƒœ ์ „์ด๋„

Process์˜ ์ข…๋ฃŒ

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

single core

  • ์ฒ˜๋ฆฌํ•ด์•ผํ•  ์ž‘์—…์ด 2๊ฐœ (A, B)

์™ผ์ชฝ ๊ทธ๋ฆผ์€ single thread๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ณ , ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์€ 2๊ฐœ์˜ thread๋ฅผ ์ด์šฉํ•ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ๊ฒฝ์šฐ, ๋‘ ์ž‘์—…์ด ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๊ฐ€ ๋‚œ๋‹ค.

  • ์†๋„๋ฉด์—์„œ ์™ผ์ชฝ ์‚ฌ์ง„์ด ๋” ๋น ๋ฅด๋‹ค.
    ์™œ? context switching์ด ์ผ์–ด๋‚˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

multi core (core 2๊ฐœ)

  • ๋Œ€๋ถ€๋ถ„์€ multi core๊ฐ€ ๋˜์–ด์žˆ๋‹ค.
  • ๊ณต์œ ์ž์›์˜ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€๋งŒ ์†๋„๋ฉด์—์„œ ์ด์ ์ด ์žˆ๋‹ค.
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);
		
		// multi-core ํ™˜๊ฒฝ์—์„œ๋Š” ์šฐ์„ ์ˆœ์œ„์˜ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค 
        // (single core์—์„œ๋งŒ ์ ์šฉ๋˜๊ณ  ์˜๋ฏธ์žˆ์Œ)
        // minimu = 0, maximum = 10 ํด์ˆ˜๋ก ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค
		t1.setPriority(10);
		t2.setPriority(2);
        
		t1.start();
		t2.start();
		
		System.out.println("main thread ์ข…๋ฃŒ");
	}
}

Daemon Thread (๋ฐ๋ชฌ ์Šค๋ ˆ๋“œ)

๋‹ค๋ฅธ ์ผ๋ฐ˜ Thread์— ๋ณด์กฐ์ ์ธ ์ž‘์—…์„ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

  • Daemone Thread๋ฅผ ํŒŒ์ƒ์‹œํ‚จ thread๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๋”ฐ๋ผ์„œ ์ข…๋ฃŒ๋œ๋‹ค.
  • main thread๊ฐ€ dead ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ๋๋‚˜์ง€ ์•Š์•˜์–ด๋„ ๊ฐ™์ด ์ข…๋ฃŒ๋œ๋‹ค.
  • ๋Œ€ํ‘œ์ ์ธ daemon thread์˜ ์˜ˆ
    1 ) garbage collector
    garbage collector๋Š” ๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๋ฉ”์ธ์ด ์ข…๋ฃŒ๋˜๋ฉด ๊ฐ™์ด ์ข…๋ฃŒ๋œ๋‹ค.
    2 ) ์›Œ๋“œ ํ”„๋กœ์„ธ์„œ์˜ ์ž๋™์ €์žฅ
t1.setDaemon(true);

์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด๊ธฐ (Daemon Thread)

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 ์Šค๋ ˆ๋“œ๊ฐ€ sleep)
			}catch(Exception e) {
			}
			System.out.println(i);
			
			if (i == 5) {
				autoSave = true;
			}
		}
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3000); // t Thread๋ฅผ sleep ์‹œํ‚ด 
			} catch(InterruptedException e) {
				
			}
			
			if(autoSave) {
				System.out.println("์ž๋™์ €์žฅ๋˜์—ˆ์–ด์š”!");
			}
		}
	}
}

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

  • ์ƒ์„ฑ
  • start( )
  • sleep( )
  • stop( ) (์•„๋ž˜ 3๊ฐœ ์ด์ œ ์•ˆ ์”€ โŒ)
    1 ) stop( ) - Thread์˜ ์ข…๋ฃŒ(๊ฐ•์ œ)
    2 ) suspend( ) - Thread์˜ ์ผ์‹œ์ค‘์ง€
    3 ) resume( ) - ์ผ์‹œ์ค‘์ง€๋œ Thread์˜ ์žฌ์‹œ์ž‘
  • interrupt( ), interrupted( ) [ํ™•์ธ] , isInterrupted( ) [ํ™•์ธ]
  • yield( )

1. sleep( long millisecond )

  • ์ผ์ •์‹œ๊ฐ„๋™์•ˆ thread๋ฅผ ์ค‘์ง€์‹œํ‚จ๋‹ค.
  • 'sleep'์—์„œ ๊นจ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ
    • ์ง€์ •๋œ ์‹œ๊ฐ„์ด ๋‹ค ๋˜๋Š” ๊ฒฝ์šฐ
    • ํ•ด๋‹น ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด interrupt( )๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ํ•ด๋‹น ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด์„œ interruptedException์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ
  • sleep์—์„œ ๊นจ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ์—๋Š” Runnable ์ƒํƒœ๋กœ ๊ฐ„๋‹ค.

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); // ํ˜„์žฌ ์‹คํ–‰๋˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์šฐ๋Š” ๊ฒƒ 
							// -> ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ main ์Šค๋ ˆ๋“œ๊ฐ€ ์žฌ์šฐ๊ฒŒ ๋จ
		}catch (Exception e) {
			
		}
		System.out.println("<<main 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 ์ข…๋ฃŒ>>");
	}
}
//2์ดˆ ๋™์•ˆ Thread1 ์ž๊ณ ์žˆ์Œ
// main ์Šค๋ ˆ๋“œ ์‹คํ–‰
// Thread2 ์‹คํ–‰
// Thread1 ์‹คํ–‰

2. interrupt( )

  • stop( ) -> thread ๊ฐ•์ œ ์ค‘์ง€ -> X, ์‚ฌ์šฉ๋ถˆ๊ฐ€ ( deprecated )
  • start( ) -> thread ์‹œ์ž‘! (์ด๊ฒƒ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ)

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

  • interrupt( )๋ฅผ ์ด์šฉ -> ์ง์ ‘ ์ค‘์ง€์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.
  • thread์˜ ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ’์ธ Interrupted State๋ฅผ true๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.
    (์ดํ›„ ๋‚ด๋ถ€ ๋กœ์ง์„ ํ†ตํ•ด Thread๋ฅผ ์ค‘์ง€ํ•œ๋‹ค)

thread๊ฐ€ interrupt๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ

  • interrupted( ) : Thread์˜ static (ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ)
    ํ˜„์žฌ ์ˆ˜ํ–‰์ค‘์ธ thread๊ฐ€ interrupt๊ฐ€ ๊ฑธ๋ ธ๋Š”์ง€ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํŠน์ • ์Šค๋ ˆ๋“œ๋ฅผ ์ง€์นญํ•  ์ˆ˜ ์—†๋‹ค...
    ์ƒํƒœ๊ฐ’์„ ์กฐ์‚ฌํ•˜๊ณ  ๊ทธ ์ƒํƒœ๊ฐ’์„ false๋กœ ๋ฐ”๊พผ๋‹ค. (์กฐ์‹ฌ~๐Ÿ™‹โ€โ™€๏ธ)
  • isInterrupted( ) : static์ด ์•„๋‹ˆ๋‹ค.
    ํŠน์ • ์Šค๋ ˆ๋“œ๋ฅผ ์ง€์นญํ•ด์„œ interrupt๊ฐ€ ๊ฑธ๋ ธ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค
    ์ƒํƒœ๊ฐ’๋งŒ true/false๋กœ return ํ•ด์ค€๋‹ค
package lecture0714;

import javax.swing.JOptionPane;

class ThreadEx_04 extends Thread{
	@Override
	public void run() {
		int i = 10;
		while (i != 0 && !isInterrupted()) {
			System.out.println(--i);
            
            // ์ด ๋ถ€๋ถ„ ๋„ˆ๋ฌด ๊ตฌ๋ ค์š”.. ๋ฐ‘์—์„œ ๋ฐ”๊ฟ”๋ด์š”..!
			for(long k=0; k<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("๊ฐ’์„ ์ž…๋ ฅํ•˜์„ธ์š”!");
		System.out.println("์ž…๋ ฅ๊ฐ’์€ : "+input);
		
		t.interrupt();
		// Thread t์˜ interrupt ์ƒํƒœ๊ฐ€ true๊ฐ€ ๋œ๋‹ค.
		System.out.println("Thread ์ƒํƒœ๊ฐ’์€ : "+t.isInterrupted());
	} 
}

/*
9
8
7
6
5
4
3
์ž…๋ ฅ๊ฐ’์€ : 14
Thread ์ƒํƒœ๊ฐ’์€ : true
์นด์šดํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์–ด์š”
*/

sleep์—์„œ interrupt๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ

package lecture0714;

import javax.swing.JOptionPane;

class ThreadEx_04 extends Thread{
	@Override
	public void run() {
		int i = 10;
		while (i != 0 && !isInterrupted()) {
			System.out.println(--i);

//			for(long k=0; k<2500000000L; k++) { // ์‹œ๊ฐ„์ง€์—ฐ
//			}
			// sleep ์ด์šฉํ•œ ์ฝ”๋“œ๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค~!
            // ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค..
			try {
				Thread.sleep(4000);
				// ์ž๊ณ  ์žˆ์„ ๋•Œ interrupt๊ฐ€ ๊ฑธ๋ฆฐ๋‹ค.
				// ์ผ์–ด๋‚˜๊ฒŒ ๋˜๋ฉด ์ž๊ธฐ์˜ intrrupted ์ƒํƒœ๋ฅผ false๋กœ ์ดˆ๊ธฐํ™”์‹œํ‚จ๋‹ค.
				// ๋”ฐ๋ผ์„œ sleep์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ์ˆซ์ž๊ฐ€ ์ค‘๋‹จ๋˜์ง€ ์•Š๊ณ  ๊ณ„์† ๋Œ์•„๊ฐ„๋‹ค.
			} catch(Exception e) {
           		// interrupt๊ฐ€ false์ธ ์ƒํƒœ๋กœ ๋˜์–ด ์žˆ๋‹ค.
				// ๋”ฐ๋ผ์„œ catch๋ฌธ์—์„œ interrupt๋ฅผ ํ•œ ๋ฒˆ ๋” ๊ฑธ์–ด์ค˜์•ผ ๋œ๋‹ค.
				interrupt();
			}
		}
		System.out.println("์นด์šดํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์–ด์š”");
	}
}

public class ThreadExam04 {
	public static void main(String[] args) {
		Thread t = new ThreadEx_04();
		t.start();
		
		String input = JOptionPane.showInputDialog("๊ฐ’์„ ์ž…๋ ฅํ•˜์„ธ์š”!");
		System.out.println("์ž…๋ ฅ๊ฐ’์€ : "+input);
		
		t.interrupt();
		// Thread t์˜ interrupt ์ƒํƒœ๊ฐ€ true๊ฐ€ ๋œ๋‹ค.
		System.out.println("Thread ์ƒํƒœ๊ฐ’์€ : "+t.isInterrupted());
	} 
}

/*
9
8
7
6
5
4
3
์ž…๋ ฅ๊ฐ’์€ : 14
Thread ์ƒํƒœ๊ฐ’์€ : true
2
1
์นด์šดํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์–ด์š”
*/

3. stop( ), suspend( )

์ง€๊ธˆ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋‹ค.
ํ•˜์ง€๋งŒ ๋กœ์ง์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

package lecture0714;

class ThreadEx_05 implements Runnable{
	@Override
	public void run() {
		while(true) {
			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 3๊ฐœ
		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);
			t1.suspend(); // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			t2.suspend(); // t2๋ฅผ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			t1.resume(); // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			t1.stop();
			t2.stop();
			Thread.sleep(2000);
			t3.stop();
		} catch (Exception e) {
			
		}
	}
}

๋กœ์ง์œผ๋กœ ๊ฐ™์€ ์ฝ”๋“œ ์งœ๋ณด๊ธฐ

package lecture0714;

/* ๊ฐ™์€ ๋™์ž‘ ๋กœ์ง์œผ๋กœ ๋ฐ”๊ฟ”๋ณด์ž */
class ThreadEx_06 implements Runnable{
	
	// boolean suspended = false;
	// boolean stopped = false;
  	volatile boolean suspended = false;
	volatile boolean stopped = false;
	
	@Override
	public void run() {
		while(!stopped) {
			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 3๊ฐœ
		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);
			r1.suspend(); // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r2.suspend(); // t2๋ฅผ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r1.resume(); // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			r1.stop();
			r2.stop();
			Thread.sleep(2000);
			r3.stop();
		} catch (Exception e) {
			
		}
	}
}

๋กœ์ง์— ๋ฌธ์ œ๊ฐ€ ์—†๋Š”๋ฐ ์ฝ”๋“œ๊ฐ€ ์ผ๋ถ€ ์ด์ƒํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
๋‹ค์Œ์€ ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์Šค์—์„œ ๋™์ž‘ํ•˜๋Š” ๋กœ์ง์ด๋‹ค.

volatile ํ‚ค์›Œ๋“œ

๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด cache๊ฐ€ ์•„๋‹Œ memory์—์„œ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๋ผ๋Š” ํ‚ค์›Œ๋“œ ๋ถ™๋Š”๋‹ค.

4. yield( )

Thread๊ฐ€ ์ž์‹ ์—๊ฒŒ ์ฃผ์–ด์ง„ ์‹คํ–‰์‹œ๊ฐ„์„ ๋‹ค ์“ฐ์ง€์•Š๊ณ  ๋‹ค๋ฅธ Thread์—๊ฒŒ ์–‘๋ณดํ•ด์ค€๋‹ค.

package lecture0714;

/* ๊ฐ™์€ ๋™์ž‘ ๋กœ์ง์œผ๋กœ ๋ฐ”๊ฟ”๋ณด์ž */
class ThreadEx_06 implements Runnable{
	
	volatile boolean suspended = false;
	volatile boolean stopped = false;
	
	@Override
	public void run() {
		while(!stopped) {
			if (!suspended) {
				System.out.println(Thread.currentThread().getName());
				try {
					Thread.sleep(1000);
				}catch(Exception e) {
					
				}
			} else {
				Thread.yield(); // ์–‘๋ณด๋ฅผ ํ†ตํ•ด busy waiting์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
			}
			
		}
		
	}
	
	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 3๊ฐœ
		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);
			r1.suspend(); // t1์„ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r2.suspend(); // t2๋ฅผ ์ผ์‹œ ์ค‘์ง€
			Thread.sleep(2000);
			r1.resume(); // t1์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •
			Thread.sleep(2000);
			r1.stop();
			r2.stop();
			Thread.sleep(2000);
			r3.stop();
		} catch (Exception e) {
			
		}
	}
}

yield์— ๋Œ€ํ•œ ์ƒํƒœ์ „์ด๋„

5. join( )

  • ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ๋Š” thread๊ฐ€ ๋‹ค๋ฅธ ํŠน์ • thread๋ฅผ ์ง€์ •ํ•ด์„œ ๊ทธ thread๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰์‹œํ‚ค๋Š” ๋ฉ”์„œ๋“œ๋‹ค. ( instance method )
  • sleep์€ static method ์ด๋ฏ€๋กœ ํŠน์ • thread๋ฅผ ์žฌ์šธ ์ˆ˜ ์—†๊ณ , ํ˜„์žฌ ์‹คํ–‰๋˜๋Š” thread๋ฅผ ์žฌ์šธ ์ˆ˜ ์žˆ๋‹ค.
  1. join( )
  2. join(long ์ดˆ)

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 {
			// ๋‚ด๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์„ hold ์‹œํ‚ค๊ณ , ์ง€์ •ํ•œ thread๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ํ•จ
			// ์‹คํ–‰์ค‘์ธ main thread๋ฅผ ์ผ์‹œ์ ์œผ๋กœ block์‹œํ‚ด
			// blocked๋œ thread๋ฅผ Runnable ์ƒํƒœ๋กœ ๋ณ€ํ™˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด try-catch๋ฌธ ์‚ฌ์šฉํ•จ
			t1.join();
			t2.join();
		} catch (Exception e) {
			// TODO: handle exception
		}
		System.out.println("<<main>> ์ข…๋ฃŒ"); 
	}
}

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

join๋ฌธ์„ ์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊นŒ?

์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด์•„์š”
package lecture0715;

class ThreadEx_08_1 extends Thread{
	
	final static int MAX_MEMORY = 1000;
	int usedMemory = 0;
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(10000); // 10์ดˆ ๋™์•ˆ ์ž์š”!
			} catch (Exception e) {
				System.out.println("interrupt์— ์˜ํ•ด์„œ ๊นจ์–ด๋‚ฌ์–ด์š”!");
			}
			gc();
			System.out.println("๋ฉ”๋ชจ๋ฆฌ ์ฒญ์†Œ ์™„๋ฃŒ! ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ๋Ÿ‰์€:"
					+ freeMemory());
		} 
	}
	public void gc() {
		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 t1 = new ThreadEx_08_1();
		t1.setDaemon(true);
		t1.start();
		
		int requiredMemory = 0;
		
		for(int i=0; i<20; i++) {
			requiredMemory = ((int)(Math.random() * 10)) * 20;
							 // 0.0๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฌ๊ณ  200๋ณด๋‹ค ์ž‘์€ ์ •์ˆ˜
			
			// ํ•„์š”ํ•œ memory๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–‘๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ 
			// ํ˜„์žฌ ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ์–‘์˜ 60%์ด์ƒ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„ ๋•Œ gc๋ฅผ ์‹คํ–‰
			if ((t1.freeMemory() < requiredMemory) ||
					(t1.freeMemory() < t1.totalMemory() * 0.4)) {
				t1.interrupt(); // ์—ฌ๊ธฐ์„œ gc() ์‹คํ–‰์ด ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์•„์š”!
				try {
					t1.join(100);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
			// ์ฒญ์†Œ๊ฐ€ ๋˜์—ˆ์œผ๋‹ˆ ๋ฉ”๋ชจ๋ฆฌ์–‘์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
			t1.usedMemory += requiredMemory;
			System.out.println("์‚ฌ์šฉ๋œ ๋ฉ”๋ชจ๋ฆฌ๋Ÿ‰ :" +t1.usedMemory);
		}
	
	}
}

Thread์˜ ๋™๊ธฐํ™”

ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ์˜ thread๊ฐ€ ๊ณต์šฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

T1์ด 1๋ฒˆ์„ ์„ ํƒํ•˜๊ณ  ์นด๋“œ ๊ฒฐ์ œํ•˜๊ณ  ์žˆ๋Š” ์™€์ค‘์—๋Š” ๋‹ค๋ฅธ T๊ฐ€ ๋ฐฉํ•ดํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰์•„์ค˜์•ผ ๋œ๋‹ค.

1 ) Critical section(์ž„๊ณ„ ์˜์—ญ)์„ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
2 ) Lock(Monitor)์„ ๋„์ž…ํ•ด์„œ ์ž„๊ณ„ ์˜์—ญ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

6. Lock( )

  • T1์ด Lock์„ ๊ฐ€์ ธ๊ฐ€์„œ ๋‹ค๋ฅธ T๊ฐ€ ๊ณต์šฉ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชป ํ•˜๋„๋ก ํ•œ๋‹ค.
  • T1์ด ์ž‘์—…์„ ๋๋งž์น˜๋ฉด Lock์„ ๋ฐ˜๋‚ฉํ•˜๊ณ , ๋Œ€๊ธฐ์ƒํƒœ์— ์žˆ๋˜ ๋‹ค๋ฅธ T๊ฐ€ Lock์„ ์žก๋Š”๋‹ค.
  • ํš๋“ํ•˜์ง€ ๋ชปํ•œ ๋‹ค๋ฅธ T๋Š” ๋˜ ๋Œ€๊ธฐ๋ฅผ ํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ Lock์„ ์–ป์–ด์„œ ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Java์—์„œ "Lock"์„ ์–ป์–ด ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•˜๋ ค๋ฉด synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค.

Synchronized(๋™๊ธฐํ™”)

  1. method ๋™๊ธฐํ™”
  2. ๋™๊ธฐํ™” block์„ ์ƒ์„ฑ (๋” ํšจ์œจ์ด ์ข‹์Œ)

1. method ๋™๊ธฐํ™” ์ฝ”๋“œ (์€ํ–‰ ์ถœ๊ธˆ)

package lecture0715;

// Thread์— ์˜ํ•ด์„œ ๊ณต์œ ๋˜๋Š” ๊ณต์œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ class
class Account{
	private int balance = 1000; //๊ณ„์ขŒ ์ž”์•ก
	public int getBalance() {
		return balance;
	}
	// ์ถœ๊ธˆํ•˜๋Š” method => ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ
	public synchronized void withdraw(int money) {
		if (balance >= money) {
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
				// TODO: handle exception
			}
			balance -= money;
		}
	}
}
class ThreadEx_09 implements Runnable{
	Account acc = new Account();
	
	@Override
	public void run() {
		while(acc.getBalance()>0) {
			int money = ((int)(Math.random() * 3 + 1)*100);
			acc.withdraw(money);
			System.out.println("๋‚จ์€ ์ž”์•ก :" + acc.getBalance());
		}	
	}
}
public class ThreadExam09 {
	public static void main(String[] args) {
		ThreadEx_09 r = new ThreadEx_09(); // runnable ๊ฐ์ฒด
		
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		
		t1.start();
		t2.start();
	}
	
}

๋งŒ์•ฝ synchronized๋œ ๋ฉ”์„œ๋“œ์˜ ์ฝ”๋“œ๊ฐ€ ๊ธธ ๊ฒฝ์šฐ,
๋ฉ”์„œ๋“œ ์•ˆ์—๋Š” ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ์ฝ”๋“œ์™€ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ํ˜ผ์žฌํ•œ๋‹ค.
๋”ฐ๋ผ์„œ ํšจ์œจ์„ ์œ„ํ•ด ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋™๊ธฐํ™”๋ฅผ ์‹œ์ผœ ๋ฒ”์œ„๋ฅผ ์ค„์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๊ทธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ ๋ถ€๋ถ„์ด๋‹ค.

2. ๋™๊ธฐํ™” ๋ธ”๋ก ์ฝ”๋“œ

// Thread์— ์˜ํ•ด์„œ ๊ณต์œ ๋˜๋Š” ๊ณต์œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ class
class Account{
	private int balance = 1000; //๊ณ„์ขŒ ์ž”์•ก
	public int getBalance() {
		return balance;
	}
	// ์ถœ๊ธˆํ•˜๋Š” method => ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ
	public void withdraw(int money) {
		// ๋™๊ธฐํ™” ๋ธ”๋ก
		synchronized(this) { // ์ธ์ž์—๋Š” ์–ด๋–ค ๊ฐ์ฒด์— ๋Œ€ํ•ด ๋™๊ธฐํ™” ํ• ์ง€
			if (balance >= money) {
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
				balance -= money;
			}
		}
	}
}

Synchronized์˜ ๋น„ํšจ์œจ

Synchronized๋ฅผ ์ด์šฉํ•ด์„œ ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๊ฒƒ์€ ์ข‹์€ ๋ถ€๋ถ„์ด๋‹ค.
ํ•˜์ง€๋งŒ Thread๊ฐ€ ๊ณต์œ ์ž์›์— ๋Œ€ํ•œ Lock์„ ํš๋“ํ•œ ํ›„ ๋ณ„๋‹ค๋ฅธ ์ผ์„ ํ•˜์ง€์•Š๊ณ  ์˜ค๋žœ์‹œ๊ฐ„ lock๋งŒ ๊ณ„์† ๋“ค๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ฆ‰, ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ๋‹ค๋ฅธ Thread์— ๋Œ€ํ•ด์„œ starvation ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ 2๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

  1. wait( ) - Lock์„ ๋†“๊ณ  ์ผ์‹œ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋†“์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฉ”์„œ๋“œ
  2. notify( ) - ๋Œ€๊ธฐ์ƒํƒœ์— ์žˆ๋Š” Thread๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก block์„ ํ•ด์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ

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