[JAVA] Thread

๊ฐ•๋ฏผ์Šนยท2023๋…„ 8์›” 31์ผ
1

JAVA

๋ชฉ๋ก ๋ณด๊ธฐ
8/15

๐Ÿ“Œ Thread

๐Ÿ“ ๊ฐœ์š”

์•ž์„œ ์šด์˜์ฒด์ œ๋ฅผ ํ•˜๋ฉด์„œ ์“ฐ๋ ˆ๋“œ์— ๋Œ€ํ•ด ํฌ์ŠคํŒ…์„ ํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ƒ๊ธฐํ•ด๋ณด์ž.

์‹ค์ œ๋กœ ๋™์‹œ์— ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ๊ฐœ์ˆ˜๋Š” CPU ์ฝ”์–ด์˜ ๊ฐœ์ˆ˜์™€ ๋™์ผํ•œ๋ฐ, ์ด๋ณด๋‹ค ๋งŽ์€ ๊ฐœ์ˆ˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋‘ ํ•จ๊ป˜ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜๋Š” ์—†๋‹ค.

๊ฐ ์ฝ”์–ด๋“ค์€ ์•„์ฃผ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ํ†ตํ•ด ๋™์‹œ์— ๋™์ž‘ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•  ๋ฟ์ด๋‹ค.

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

๐Ÿ“ Thread ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

Thread๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€ํ‘œ์ ์œผ๋กœ 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

class ThreadEx1_1 extends Thread {
	public void run() {
    	// ๋กœ์ง
    }
}

class ThreadEx1_2 implements Runnable {
	public void run() {
    	// ๋กœ์ง
    }
}

์ฒซ ๋ฒˆ์งธ๋Š” Thread๋ฅผ ์ƒ์†๋ฐ›๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. Thread๋Š” ์–ธ์ œ๋“ ์ง€ ์ƒ์†์ด ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๊ณ , ์ด๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด run์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋‘ ๋ฒˆ์งธ๋Š” Runnable์„ implements๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
Runnable์ด๋ž€, Thread๋ฅผ ์ƒ์†๋ฐ›๊ณ  ์žˆ๋Š” Class์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฅผ ์ƒ์†ํ•จ์œผ๋กœ์จ, ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•๋Š”๋‹ค.

๋ณดํ†ต ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•œ๋‹ค.
Java์˜ extends์˜ ์ƒ์† ๋ฐฉ์‹์€ ํ•˜๋‚˜์˜ class๋งŒ ๊ฐ€๋Šฅํ•œ ๋ฐ˜๋ฉด, implements๋ฅผ ํ†ตํ•ด ๋‹ค์ค‘ ์ƒ์† ๊ธฐ๋Šฅ์„ ํ†ตํ•ด run์„ ์˜ค๋ฒ„ ๋ผ์ด๋”ฉ ํ•ด์•ผํ•œ๋‹ค.

Thread์˜ ์ƒ์„ฑ์ž์™€ ๋ฉ”์„œ๋“œ

1) ์ƒ์„ฑ์ž

  • Thread( ) : ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ ๊ฐ์ฒด ํ• ๋‹น
  • Thread(String name) : ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ ๊ฐ์ฒด๊ฐ€ ํ• ๋‹น๋˜๋ฉฐ, ์Šค๋ ˆ๋“œ ์ด๋ฆ„์€ name์œผ๋กœ ์„ค์ •๋จ
  • Thread(Runnable target) : Runnable target์ด ๊ตฌํ˜„๋œ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด ํ• ๋‹น
  • Thread(Runnable target, String name) : Runnable target์ด ๊ตฌํ˜„๋œ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด๊ฐ€ ํ• ๋‹น๋˜๋ฉด ์Šค๋ ˆ๋“œ ์ด๋ฆ„์€ name์œผ๋กœ ์„ค์ •๋จ.

2) ๋ฉ”์†Œ๋“œ

  • void run( ) : ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋˜๋Š” ๋ฉ”์†Œ๋“œ๋กœ ์‚ฌ์šฉ์ž๋Š” run() ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    -void start( ) : ์Šค๋ ˆ๋“œ๊ฐ€ ์‹œ์ž‘๋˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋กœ JVM์€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ run() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • void interrupt( ) : ์Šค๋ ˆ๋“œ๋ฅผ ์ค‘์ง€ ์‹œํ‚ต๋‹ˆ๋‹ค.
  • void join( ) : ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
  • void join(long millis) : ์ตœ๋Œ€ millis ์‹œ๊ฐ„๋™์•ˆ ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
  • static void sleep(long millis) : millis ์‹œ๊ฐ„๋™์•ˆ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ผ์‹œ์ค‘์ง€์‹œํ‚ต๋‹ˆ๋‹ค.
  • static void yield( ) : ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์‹œ๊ฐ„์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์–‘๋ณดํ•ฉ๋‹ˆ๋‹ค.
  • static Thread currentThread( ) : ํ˜„์žฌ ์‹คํ–‰์ค‘์ธ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด์˜ ์ฐธ์กฐ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • long getId( ) : ์Šค๋ ˆ๋“œ์˜ Id๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • String getName( ) : ์Šค๋ ˆ๋“œ์˜ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • int getPriority( ) : ์Šค๋ ˆ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. (์šฐ์„ ์ˆœ์œ„ ๋ฒ”์œ„ : 1 ~ 10)
  • Thread.State getState( ) : ์Šค๋ ˆ๋“œ์˜ state ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ThreadGroup getThreadGroup( ) : ์Šค๋ ˆ๋“œ๊ฐ€ ์†ํ•œ ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • static boolean interrupted( ) : ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ interrupted ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • boolean isInterrupted( ) : ์ด ์Šค๋ ˆ๋“œ์˜ interrupted ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • boolean isAlive( ) : ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • boolean isDaemon( ) : ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐ๋ชฌ ์Šค๋ ˆ๋“œ์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • void setDaemon(boolean on) : ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ๋ชฌ ์Šค๋ ˆ๋“œ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • void setName(String name) : ์ด ์Šค๋ ˆ๋“œ์˜ ์ด๋ฆ„์„ name์œผ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • void setPriority(int newPriority) : ์ด ์Šค๋ ˆ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ newPriority๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • String toString( ) : ์ด ์Šค๋ ˆ๋“œ์˜ ์ด๋ฆ„, ์šฐ์„ ์ˆœ์œ„, ์Šค๋ ˆ๋“œ๊ทธ๋ฃน๋“ฑ์˜ ์ •๋ณด๋ฅผ ๋‹ด์€ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

cf) static ๋ฉ”์†Œ๋“œ๋Š” ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ ์ž์‹ ์—๊ฒŒ ์ ์šฉ๋œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ์‹คํ–‰

์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์€ run() ํ˜ธ์ถœ์ด ์•„๋‹Œ start() ํ˜ธ์ถœ๋กœ ํ•ด์•ผํ•œ๋‹ค.

Why?

์šฐ๋ฆฌ๋Š” ๋ถ„๋ช… run() ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ–ˆ๋Š”๋ฐ, ์‹ค์ œ ์Šค๋ ˆ๋“œ ์ž‘์—…์„ ์‹œํ‚ค๋ ค๋ฉด start()๋กœ ์ž‘์—…ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

run()์œผ๋กœ ์ž‘์—… ์ง€์‹œ๋ฅผ ํ•˜๋ฉด ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์„ ์•ˆํ• ๊นŒ? ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. ๋‘ ๋ฉ”์†Œ๋“œ ๋ชจ๋‘ ๊ฐ™์€ ์ž‘์—…์„ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ run() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์ด๊ฑด ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.


Java์—๋Š” ์ฝœ ์Šคํƒ(call stack)์ด ์žˆ๋‹ค. ์ด ์˜์—ญ์ด ์‹ค์งˆ์ ์ธ ๋ช…๋ น์–ด๋“ค์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋กœ, ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ ์‹คํ–‰์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋งŒ์•ฝ ๋™์‹œ์— ๋‘ ๊ฐ€์ง€ ์ž‘์—…์„ ํ•œ๋‹ค๋ฉด, ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ฝœ ์Šคํƒ์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.

์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค๋Š” ๊ฑด, JVM์ด ๋‹ค์ˆ˜์˜ ์ฝœ ์Šคํƒ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์ผ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์‚ฌ์šฉ์ž๋Š” ๋™์‹œ์— ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์—ฌ์ค€๋‹ค.

์ฆ‰, run() ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ main()์˜ ์ฝœ ์Šคํƒ ํ•˜๋‚˜๋งŒ ์ด์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์Šค๋ ˆ๋“œ ํ™œ์šฉ์ด ์•„๋‹ˆ๋‹ค. (๊ทธ๋ƒฅ ์Šค๋ ˆ๋“œ ๊ฐ์ฒด์˜ run์ด๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๊ฒŒ ๋˜๋Š” ๊ฒƒ..)

start() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, JVM์€ ์•Œ์•„์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์œ„ํ•œ ์ฝœ ์Šคํƒ์„ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ณ  context switching์„ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๋‹ต๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ํ•ด์ค€๋‹ค.

์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์ฝœ ์Šคํƒ์„ ๋งŒ๋“ค์–ด ์ž‘์—…์„ ํ•ด์•ผ ์Šค๋ ˆ๋“œ ์ผ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— start() ๋ฉ”์†Œ๋“œ๋ฅผ ์จ์•ผํ•˜๋Š” ๊ฒƒ์ด๋‹ค!

start()๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ฝœ ์Šคํƒ์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ run()์„ ํ˜ธ์ถœํ•ด์„œ ๊ทธ ์Šคํƒ ์•ˆ์— run()์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์ œ์–ด

์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๋Š” 5๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค

  • NEW : ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์•„์ง start()๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ์ƒํƒœ
  • RUNNABLE : ์‹คํ–‰ ์ค‘ ๋˜๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅ ์ƒํƒœ
  • BLOCKED : ๋™๊ธฐํ™” ๋ธ”๋Ÿญ์— ์˜ํ•ด ์ผ์‹œ์ •์ง€๋œ ์ƒํƒœ(lock์ด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ)
  • WAITING, TIME_WAITING : ์‹คํ–‰๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ์ผ์‹œ์ •์ง€ ์ƒํƒœ
  • TERMINATED : ์Šค๋ ˆ๋“œ ์ž‘์—…์ด ์ข…๋ฃŒ๋œ ์ƒํƒœ

์Šค๋ ˆ๋“œ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์šด ์ด์œ ๋Š” ๋ฐ”๋กœ ๋™๊ธฐํ™”์™€ ์Šค์ผ€์ค„๋ง ๋•Œ๋ฌธ์ด๋‹ค.

์Šค์ผ€์ค„๋ง๊ณผ ๊ด€๋ จ๋œ ๋ฉ”์†Œ๋“œ๋Š” sleep(), join(), yield(), interrupt()์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค.

start() ์ดํ›„์— join()์„ ํ•ด์ฃผ๋ฉด main ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋‘ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ์ผ๋„ ํ•ด์ค€๋‹ค.



๐Ÿ“ ๋™๊ธฐํ™”

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ๊ตฌํ˜„์„ ํ•˜๋‹ค๋ณด๋ฉด, ๋™๊ธฐํ™”๋Š” ํ•„์ˆ˜์ ์ด๋‹ค.

๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋Š”, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ๋‚ด์˜ ์ž์›์„ ๊ณต์œ ํ•˜๋ฉด์„œ ์ž‘์—…ํ•  ๋•Œ ์„œ๋กœ์˜ ์ž‘์—…์ด ๋‹ค๋ฅธ ์ž‘์—…์— ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์Šค๋ ˆ๋“œ์˜ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด์„ , ์ž„๊ณ„ ์˜์—ญ(critical section)๊ณผ ์ž ๊ธˆ(lock)์„ ํ™œ์šฉํ•œ๋‹ค.

์ž„๊ณ„์˜์—ญ์„ ์ง€์ •ํ•˜๊ณ , ์ž„๊ณ„์˜์—ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” lock์„ ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—๊ฒŒ๋งŒ ๋นŒ๋ ค์ฃผ๋Š” ๊ฐœ๋…์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ž„๊ณ„๊ตฌ์—ญ ์•ˆ์—์„œ ์ˆ˜ํ–‰ํ•  ์ฝ”๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด, lock์„ ๋ฐ˜๋‚ฉํ•ด์ค˜์•ผ ํ•œ๋‹ค.


์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•

  • ์ž„๊ณ„ ์˜์—ญ(critical section) : ๊ณต์œ  ์ž์›์— ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก(ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ๊ฐ€๋Šฅ)
  • ๋ฎคํ…์Šค(mutex) : ๊ณต์œ  ์ž์›์— ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก(์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋„ ๊ฐ€๋Šฅ)
  • ์ด๋ฒคํŠธ(event) : ํŠน์ •ํ•œ ์‚ฌ๊ฑด ๋ฐœ์ƒ์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์•Œ๋ฆผ
  • ์„ธ๋งˆํฌ์–ด(semaphore) : ํ•œ์ •๋œ ๊ฐœ์ˆ˜์˜ ์ž์›์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ ‘๊ทผ ์ œํ•œ
  • ๋Œ€๊ธฐ ๊ฐ€๋Šฅ ํƒ€์ด๋จธ(waitable timer) : ํŠน์ • ์‹œ๊ฐ„์ด ๋˜๋ฉด ๋Œ€๊ธฐ ์ค‘์ด๋˜ ์Šค๋ ˆ๋“œ ๊นจ์›€

synchronized ํ™œ์šฉ

synchronized๋ฅผ ํ™œ์šฉํ•ด ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐ์ฒด๊ฐ€ ๋™๊ธฐํ™”๋ฅผ ํ•˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ™์ด ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์„œ ์ด์šฉํ•˜๋ฉด, ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ง„ํ–‰๋˜๋ฏ€๋กœ ์›ํ•˜๋Š” ์ถœ๋ ฅ ๊ฐ’์„ ์–ป์ง€ ๋ชปํ•œ๋‹ค.

์ด๋•Œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋˜๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ์— synchronized ํ‚ค์›Œ๋“œ๋กœ ์ž„๊ณ„์˜์—ญ์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

//synchronized : ์Šค๋ ˆ๋“œ์˜ ๋™๊ธฐํ™”. ๊ณต์œ  ์ž์›์— lock
public synchronized void saveMoney(int save){    // ์ž…๊ธˆ
    int m = money;
    try{
        Thread.sleep(2000);    // ์ง€์—ฐ์‹œ๊ฐ„ 2์ดˆ
    } catch (Exception e){

    }
    money = m + save;
    System.out.println("์ž…๊ธˆ ์ฒ˜๋ฆฌ");

}

public synchronized void minusMoney(int minus){    // ์ถœ๊ธˆ
    int m = money;
    try{
        Thread.sleep(3000);    // ์ง€์—ฐ์‹œ๊ฐ„ 3์ดˆ
    } catch (Exception e){

    }
    money = m - minus;
    System.out.println("์ถœ๊ธˆ ์™„๋ฃŒ");
}

wait()๊ณผ notify() ํ™œ์šฉ

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

  • wait() : ์Šค๋ ˆ๋“œ๊ฐ€ lock์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด, lock ๊ถŒํ•œ์„ ๋ฐ˜๋‚ฉํ•˜๊ณ  ๋Œ€๊ธฐํ•˜๊ฒŒ ๋งŒ๋“ฌ

  • notify() : ๋Œ€๊ธฐ ์ƒํƒœ์ธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๋‹ค์‹œ lock ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ณ  ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ฌ

์ด ๋‘ ๋ฉ”์†Œ๋“œ๋Š” ๋™๊ธฐํ™” ๋œ ์˜์—ญ(์ž„๊ณ„ ์˜์—ญ)๋‚ด์—์„œ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

๋™๊ธฐํ™” ์ฒ˜๋ฆฌํ•œ ๋ฉ”์†Œ๋“œ๋“ค์ด ๋ฐ˜๋ณต๋ฌธ์—์„œ ํ™œ์šฉ๋œ๋‹ค๋ฉด, ์˜๋„ํ•œ๋Œ€๋กœ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. ์ด๋•Œ wait()๊ณผ notify()๋ฅผ try-catch ๋ฌธ์—์„œ ์ ์ ˆํžˆ ํ™œ์šฉํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

/**
* ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ์ค‘ ํ˜‘๋ ฅ๊ด€๊ณ„ ์ฒ˜๋ฆฌ์ž‘์—… : wait() notify()
* ์Šค๋ ˆ๋“œ ๊ฐ„ ํ˜‘๋ ฅ ์ž‘์—… ๊ฐ•ํ™”
*/

public synchronized void makeBread(){
    if (breadCount >= 10){
        try {
            System.out.println("๋นต ์ƒ์‚ฐ ์ดˆ๊ณผ");
            wait();    // Thread๋ฅผ Not Runnable ์ƒํƒœ๋กœ ์ „ํ™˜
        } catch (Exception e) {

        }
    }
    breadCount++;    // ๋นต ์ƒ์‚ฐ
    System.out.println("๋นต์„ ๋งŒ๋“ฆ. ์ด " + breadCount + "๊ฐœ");
    notify();    // Thread๋ฅผ Runnable ์ƒํƒœ๋กœ ์ „ํ™˜
}

public synchronized void eatBread(){
    if (breadCount < 1){
        try {
            System.out.println("๋นต์ด ์—†์–ด ๊ธฐ๋‹ค๋ฆผ");
            wait();
        } catch (Exception e) {

        }
    }
    breadCount--;
    System.out.println("๋นต์„ ๋จน์Œ. ์ด " + breadCount + "๊ฐœ");
    notify();
}

์กฐ๊ฑด ๋งŒ์กฑ ์•ˆํ•  ์‹œ wait(), ๋งŒ์กฑ ์‹œ notify()๋ฅผ ๋ฐ›์•„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

profile
Step by Step goes a long way. ๊พธ์ค€ํ•˜๊ฒŒ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž ๊ฐ•๋ฏผ์Šน์ž…๋‹ˆ๋‹ค.

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