Multithread Concurrency

์˜ํ•œ๋‹˜์˜ ๊น€์˜ํ•œ์˜ ์‹ค์ „ ์ž๋ฐ” - ๊ณ ๊ธ‰ 1ํŽธ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์™€ ๋™์‹œ์„ฑ ๊ฐ•์˜๋ฅผ ์š”์•ฝํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

Process And Thread

๋ฉ€ํ‹ฐํƒœ์Šคํ‚น๊ณผ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ

ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰

ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ CPU์—์„œ ์—ฐ์‚ฐ(์‹คํ–‰)ํ•˜๋Š” ์ผ

  • CPU ์ฝ”์–ด๊ฐ€ ํ•˜๋‚˜์ผ ๊ฒฝ์šฐ, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ๋งŒ ์‹คํ–‰

  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜์˜ CPU ์ฝ”์–ด๋กœ ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” Multitasking ๊ธฐ์ˆ  ๋“ฑ์žฅ

โ„น๏ธ Multitasking

ํ•˜๋‚˜์˜ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์ด ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Šฅ๋ ฅ

  • ์šด์˜์ฒด์ œ๊ฐ€ ์Šค์ผ€์ค„๋ง์„ ์ˆ˜ํ–‰ํ•˜๊ณ , CPU๋ฅผ ์ตœ๋Œ€ํ•œ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ž‘์—…์ด ๊ณจ๊ณ ๋ฃจ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ๊ฒŒ ์ตœ์ ํ™”

  • ํ˜„๋Œ€์˜ CPU๋Š” ์ดˆ๋‹น ์ˆ˜์‹ญ์–ต ๋ฒˆ ์ด์ƒ์˜ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰

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

    • ์‹œ๋ถ„ํ• (Time Sharing) ๊ธฐ๋ฒ•: ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋ถ„ํ• ํ•ด์„œ ๋งˆ์น˜ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ํ•˜๋Š” ๊ธฐ๋ฒ•

...

โ„น๏ธ Multiprocessing

์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์—์„œ ๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์„œ(CPU Core)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ 

  • ํ•˜๋‚˜์˜ CPU ์•ˆ์— ๋ณดํ†ต 2๊ฐœ ์ด์ƒ์˜ ์ฝ”์–ด

  • ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ ์‹œ์Šคํ…œ์€ ํ•˜๋‚˜์˜ CPU ์ฝ”์–ด๋งŒ์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ๋ณด๋‹ค ๋™์‹œ์— ๋” ๋งŽ์€ ์ž‘์—… ์„ ์ฒ˜๋ฆฌ

Multiprocessing VS. Multitasking

Multiprocessing
Multitasking

์—ฌ๋Ÿฌ CPU(์—ฌ๋Ÿฌ CPU ์ฝ”์–ด)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธ

๋‹จ์ผ CPU(๋‹จ์ผ CPU ์ฝ”์–ด)๊ฐ€ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒƒ

ํ•˜๋“œ์›จ์–ด ๊ธฐ๋ฐ˜์œผ๋กœ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ

์†Œํ”„ํŠธ์›จ์–ด ๊ธฐ๋ฐ˜์œผ๋กœ CPU ์‹œ๊ฐ„์„ ๋ถ„ํ• ํ•˜์—ฌ ๊ฐ ์ž‘์—…์— ํ• ๋‹น

๋‹ค์ค‘ ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ˜„๋Œ€ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ

ํ˜„๋Œ€ ์šด์˜ ์ฒด์ œ์—์„œ ์—ฌ๋Ÿฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ํ™˜๊ฒฝ


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

โ„น๏ธ Proccess

์šด์˜์ฒด์ œ ์•ˆ์—์„œ ์‹คํ–‰์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ

  • ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ์˜ ์ธ์Šคํ„ด์Šค

    • ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ, ์šด์˜์ฒด์ œ์—์„œ ๋ณ„๋„์˜ ์ž‘์—… ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•ด์„œ ๊ด€๋ฆฌ

    • ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ์˜ ๋ฉ”๋ชจ๋ฆฌ์— ์ง์ ‘ ์ ‘๊ทผ/๊ฐ„์„ญํ•  ์ˆ˜ ์—†๋‹ค

  • ์ž๋ฐ” ์–ธ์–ด๋กœ ๋น„์œ ๋ฅผ ํ•˜์ž๋ฉด ํด๋ž˜์Šค๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๊ณ , ์ธ์Šคํ„ด์Šค๋Š” ํ”„๋กœ์„ธ์Šค

ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์„ฑ

  • Code Section: ์‹คํ–‰ํ•  ํ”„๋กœ๊ทธ๋žจ์˜ ์ฝ”๋“œ๊ฐ€ ์ €์žฅ๋˜๋Š” ๋ถ€๋ถ„

  • Data Section: ์ „์—ญ ๋ณ€์ˆ˜ ๋ฐ ์ •์  ๋ณ€์ˆ˜๊ฐ€ ์ €์žฅ๋˜๋Š” ๋ถ€๋ถ„

  • Heap: ๋™์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ

  • Stack: ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜) ํ˜ธ์ถœ ์‹œ ์ƒ์„ฑ๋˜๋Š” ์ง€์—ญ ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๊ฐ€ ์ €์žฅ๋˜๋Š” ์˜์—ญ(์Šค๋ ˆ๋“œ์— ํฌํ•จ)

...

โ„น๏ธ Thread

ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์˜ ๋‹จ์œ„

  • ํ”„๋กœ์„ธ์Šค๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ˜๋“œ์‹œ ํฌํ•จ

    • ํ•œ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋“ค์€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ณต์œ (๋‹จ์ผ ์Šค๋ ˆ๋“œ, ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ)

    • ํ”„๋กœ์„ธ์Šค๋ณด๋‹ค ๋‹จ์ˆœํ•˜๋ฏ€๋กœ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ๊ฐ€ ๋‹จ์ˆœํ•˜๊ณ  ๊ฐ€๋ณ

  • ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ๋„ ๊ทธ ์•ˆ์—์„œ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๊ฐ€ ํ•„์š”

๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์„ฑ

  • ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ: ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค์˜ ์ฝ”๋“œ ์„น์…˜, ๋ฐ์ดํ„ฐ ์„น์…˜, ํž™(๋ฉ”๋ชจ๋ฆฌ)์€ ํ”„๋กœ์„ธ์Šค ์•ˆ์˜ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ 

  • ๊ฐœ๋ณ„ ์Šคํƒ: ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ์ž์‹ ์˜ ์Šคํƒ์„ ๋ณด์œ 

ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰ ํ™˜๊ฒฝ๊ณผ ์ž์›์„ ์ œ๊ณตํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ ์—ญํ• , ์Šค๋ ˆ๋“œ๋Š” CPU๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• 


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

๋‹จ์ผ ์ฝ”์–ด ์Šค์ผ€์ค„๋ง

  • ์šด์˜์ฒด์ œ๋Š” ๋‚ด๋ถ€์— ์Šค์ผ€์ค„๋ง ํ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ์Šค์ผ€์ค„๋ง ํ์—์„œ ๋Œ€๊ธฐ

  • ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰

๋ฉ€ํ‹ฐ ์ฝ”์–ด ์Šค์ผ€์ค„๋ง

  • CPU ์ฝ”์–ด๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ฉด ํ•œ ๋ฒˆ์— ๋” ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋™์‹œ์— ์‹คํ–‰

ํ”„๋กœ์„ธ์Šค, ์Šค๋ ˆ๋“œ์™€ ์Šค์ผ€์ค„๋ง

  • ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น๊ณผ ์Šค์ผ€์ค„๋ง

    • ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธ

    • ์ด๋ฅผ ์œ„ํ•ด ์šด์˜์ฒด์ œ๋Š” ์Šค์ผ€์ค„๋ง์ด๋ผ๋Š” ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉ

    • ์Šค์ผ€์ค„๋ง์€ CPU ์‹œ๊ฐ„์„ ์—ฌ๋Ÿฌ ์ž‘์—…์— ๋‚˜๋ˆ„์–ด ๋ฐฐ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•

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

    • ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ์˜ ์ธ์Šคํ„ด์Šค

      • ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ€์ง€๋ฉฐ, ์šด์˜์ฒด์ œ์—์„œ ๋…๋ฆฝ๋œ ์‹คํ–‰ ๋‹จ์œ„๋กœ ์ทจ๊ธ‰

    • ์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ์ž‘์€ ๋‹จ์œ„

      • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์ž์›์„ ๊ณต์œ ํ•˜๋ฉฐ, ํ”„๋กœ์„ธ์Šค์˜ ์ฝ”๋“œ, ๋ฐ์ดํ„ฐ, ์‹œ์Šคํ…œ ์ž์›๋“ฑ์„ ๊ณต์œ 

      • ์‹ค์ œ๋กœ CPU์— ์˜ํ•ด ์‹คํ–‰๋˜๋Š” ๋‹จ์œ„๋Š” ์Šค๋ ˆ๋“œ

  • ํ”„๋กœ์„ธ์Šค์˜ ์—ญํ• 

    • ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰ ํ™˜๊ฒฝ(์ปจํ…Œ์ด๋„ˆ ์—ญํ• )์„ ์ œ๊ณต

      • ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„, ํŒŒ์ผ ํ•ธ๋“ค, ์‹œ์Šคํ…œ ์ž์›(๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ) ๋“ฑ์ด ํฌํ•จ

    • ํ”„๋กœ์„ธ์Šค ์ž์ฒด๋Š” ์šด์˜์ฒด์ œ์˜ ์Šค์ผ€์ค„๋Ÿฌ์— ์˜ํ•ด ์ง์ ‘ ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฉฐ, ํ”„๋กœ์„ธ์Šค ๋‚ด์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰

      • 1๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค ์•ˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ๋„ ์กด์žฌ


์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ

์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ(context switching)

  • ์Šค๋ ˆ๋“œA๋ฅผ ๋ฉˆ์ถ”๋Š” ์‹œ์ ์— CPU์—์„œ ์‚ฌ์šฉํ•˜๋˜ ๊ฐ’๋“ค์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด๋‘์–ด์•ผ ํ•œ๋‹ค.

  • ๊ทธ๋ฆฌ๊ณ  ์ดํ›„์— ์Šค๋ ˆ๋“œA๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ๋•Œ ์ด ๊ฐ’๋“ค์„ CPU์— ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ณผ์ •

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๋ถ€๋ถ„ ํšจ์œจ์ ์ด์ง€๋งŒ, ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ํ•ญ์ƒ ํšจ์œจ์ ์ธ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค

  • ํ˜„์žฌ ์ž‘์—…ํ•˜๋Š” ๋ฌธ๋งฅ์ด ๋ณ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…์ŠคํŠธ(ํ˜„์žฌ ์ž‘์—…ํ•˜๋Š” ๋ฌธ๋งฅ) ์Šค์œ„์นญ

    • ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๊ณผ์ •์—์„œ ์ด์ „์— ์‹คํ–‰ ์ค‘์ธ ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ž ๊น ์ €์žฅํ•˜๊ณ ,

    • ์ดํ›„์— ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋Š” ์‹œ์ ์— ์ €์žฅํ•œ ๊ฐ’์„ CPU์— ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•œ๋‹ค.

  • ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๊ณผ์ •์—๋Š” ์•ฝ๊ฐ„์˜ ๋น„์šฉ์ด ๋ฐœ์ƒ

    • ์—ฐ์‚ฐ ์‹œ๊ฐ„ + ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ์‹œ๊ฐ„

  • ์‹ค์ œ๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์€ ์•„์ฃผ ์งง์ง€๋งŒ ์Šค๋ ˆ๋“œ๊ฐ€ ๋งค์šฐ ๋งŽ๋‹ค๋ฉด ์ด ๋น„์šฉ์ด ์ปค์งˆ ์ˆ˜ ์žˆ์Œ

CPU์™€ ์Šค๋ ˆ๋“œ์˜ ๊ด€๊ณ„

CPU 4๊ฐœ / ์Šค๋ ˆ๋“œ 2๊ฐœ
์Šค๋ ˆ๋“œ์˜ ์ˆซ์ž๊ฐ€ ๋„ˆ๋ฌด ์ ์œผ๋ฉด ๋ชจ๋“  CPU๋ฅผ 100% ๋‹ค ํ™œ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ, 
์Šค๋ ˆ๋“œ๊ฐ€ ๋ช‡ ๊ฐœ ์—†์œผ๋ฏ€๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ์ด ์ค„์–ด๋“ ๋‹ค.

CPU 4๊ฐœ / ์Šค๋ ˆ๋“œ 100๊ฐœ
์Šค๋ ˆ๋“œ์˜ ์ˆซ์ž๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด CPU๋ฅผ 100% ๋‹ค ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ์ด ๋Š˜์–ด๋‚œ๋‹ค.

CPU 4๊ฐœ / ์Šค๋ ˆ๋“œ 4๊ฐœ
์Šค๋ ˆ๋“œ์˜ ์ˆซ์ž๋ฅผ CPU์˜ ์ˆซ์ž์— ๋งž์ถ˜๋‹ค๋ฉด CPU๋ฅผ 100% ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ๋„ ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ ์˜ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. 
์ด์ƒ์ ์œผ๋กœ๋Š” CPU ์ฝ”์–ด ์ˆ˜ + 1๊ฐœ ์ •๋„๋กœ ์Šค๋ ˆ๋“œ๋ฅผ ๋งž์ถ”๋ฉด ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ์ž ์‹œ ๋Œ€๊ธฐํ•  ๋•Œ ๋‚จ์€ ์Šค๋ ˆ๋“œ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

CPU ๋ฐ”์šด๋“œ ์ž‘์—… vs I/O ๋ฐ”์šด๋“œ ์ž‘์—…

๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋Š” ์ž‘์—…์€ ํฌ๊ฒŒ 2๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„

  • CPU-bound tasks

    • CPU์˜ ์—ฐ์‚ฐ ๋Šฅ๋ ฅ์„ ๋งŽ์ด ์š”๊ตฌํ•˜๋Š” ์ž‘์—…์„ ์˜๋ฏธ

    • ๊ณ„์‚ฐ, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‹คํ–‰ ๋“ฑ CPU์˜ ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ์ž‘์—… ์™„๋ฃŒ ์‹œ๊ฐ„์„ ๊ฒฐ์ •

    • ex. ๋ณต์žกํ•œ ์ˆ˜ํ•™ ์—ฐ์‚ฐ, ๋ฐ์ดํ„ฐ ๋ถ„์„, ๋น„๋””์˜ค ์ธ์ฝ”๋”ฉ, ๊ณผํ•™์  ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋“ฑ.

  • I/O-bound tasks

    • ๋””์Šคํฌ, ๋„คํŠธ์›Œํฌ, ํŒŒ์ผ ์‹œ์Šคํ…œ ๋“ฑ๊ณผ ๊ฐ™์€ ์ž…์ถœ๋ ฅ(I/O) ์ž‘์—…์„ ๋งŽ์ด ์š”๊ตฌํ•˜๋Š” ์ž‘์—…

    • I/O ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๋ฐœ์ƒํ•˜๋ฉฐ, CPU๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ์œ ํœด(๋Œ€๊ธฐ) ์ƒํƒœ์— ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ(์Šค๋ ˆ๋“œ๊ฐ€ CPU๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  I/O ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐ)

    • ex. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ, ํŒŒ์ผ ์ฝ๊ธฐ/์“ฐ๊ธฐ, ๋„คํŠธ์›Œํฌ ํ†ต์‹ , ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋“ฑ.

์Šค๋ ˆ๋“œ ์„ค์ •

์Šค๋ ˆ๋“œ์˜ ์ˆซ์ž๋Š” CPU-๋ฐ”์šด๋“œ ์ž‘์—…์ด ๋งŽ์€์ง€, I/O-๋ฐ”์šด๋“œ ์ž‘์—…์ด ๋งŽ์€์ง€์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •์ด ํ•„์š”

  • CPU-bound tasks: CPU ์ฝ”์–ด ์ˆ˜ + 1๊ฐœ

    • CPU๋ฅผ ๊ฑฐ์˜ 100% ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—…์ด๋ฏ€๋กœ ์Šค๋ ˆ๋“œ๋ฅผ CPU ์ˆซ์ž์— ์ตœ์ ํ™”

  • I/O-bound tasks: CPU ์ฝ”์–ด ์ˆ˜ ๋ณด๋‹ค ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑ(CPU๋ฅผ ์ตœ๋Œ€ํ•œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆซ์ž๊นŒ์ง€ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ)

    • CPU๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด CPU๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๋Š” ์ˆซ์ž๊นŒ์ง€ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ

    • ๋‹จ, ๋„ˆ๋ฌด ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ๋„ ํ•จ๊ป˜ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ ์ ์ ˆํ•œ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ํ•„์š”

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋ผ๋„ ์ƒํ™ฉ์— ๋”ฐ๋ผ CPU ๋ฐ”์šด๋“œ ์ž‘์—…์ด ๋งŽ์„ ์ˆ˜ ์žˆ๋‹ค.

์ด ๊ฒฝ์šฐ CPU-๋ฐ”์šด๋“œ ์ž‘์—…์— ์ตœ์ ํ™”๋œ CPU ์ˆซ์ž๋ฅผ ๊ณ ๋ ค


Thread creation and execution

์ž๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ

๋ฉ”์„œ๋“œ ์˜์—ญ(Method Area)

  • ๋ฉ”์„œ๋“œ ์˜์—ญ์€ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๊ณตํ†ต ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ์˜์—ญ์—์„œ ๊ณต์œ 

    • ํด๋ž˜์Šค ์ •๋ณด: ํด๋ž˜์Šค์˜ ์‹คํ–‰ ์ฝ”๋“œ(๋ฐ”์ดํŠธ ์ฝ”๋“œ), ํ•„๋“œ, ๋ฉ”์„œ๋“œ์™€ ์ƒ์„ฑ์ž ์ฝ”๋“œ๋“ฑ ๋ชจ๋“  ์‹คํ–‰ ์ฝ”๋“œ ์กด์žฌ

    • static ์˜์—ญ: static ๋ณ€์ˆ˜๋“ค์„ ๋ณด๊ด€

    • ๋Ÿฐํƒ€์ž„ ์ƒ์ˆ˜ ํ’€: ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๊ณตํ†ต ๋ฆฌํ„ฐ๋Ÿด ์ƒ์ˆ˜๋ฅผ ๋ณด๊ด€

์Šคํƒ ์˜์—ญ(Stack Area)

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

    • ์Šคํƒ ํ”„๋ ˆ์ž„: ์Šคํƒ ์˜์—ญ์— ์Œ“์ด๋Š” ๋„ค๋ชจ ๋ฐ•์Šค๊ฐ€ ํ•˜๋‚˜์˜ ์Šคํƒ ํ”„๋ ˆ์ž„. ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ํ•˜๋‚˜์˜ ์Šคํƒ ํ”„๋ ˆ์ž„์ด ์Œ“์ด๊ณ , ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ์Šคํƒ ํ”„๋ ˆ์ž„์ด ์ œ๊ฑฐ

  • ์Šคํƒ ์˜์—ญ์€ ๋” ์ •ํ™•ํžˆ ๊ฐ ์Šค๋ ˆ๋“œ๋ณ„๋กœ ํ•˜๋‚˜์˜ ์‹คํ–‰ ์Šคํƒ์ด ์ƒ์„ฑ. ๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋“œ ์ˆ˜ ๋งŒํผ ์Šคํƒ์ด ์ƒ์„ฑ

ํž™ ์˜์—ญ(Heap Area)

  • ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)์™€ ๋ฐฐ์—ด์ด ์ƒ์„ฑ๋˜๋Š” ์˜์—ญ์ด๋‹ค

  • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC)์ด ์ด๋ฃจ์–ด์ง€๋Š” ์ฃผ์š” ์˜์—ญ์ด๋ฉฐ, ๋” ์ด์ƒ ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋Š” GC์— ์˜ํ•ด ์ œ๊ฑฐ


extends Thread

Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์† ๋ฐ›๊ฑฐ๋‚˜ Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑ

thread start

Thread.start()

  • ์Šค๋ ˆ๋“œ ์‹คํ–‰ ๋ฉ”์„œ๋“œ

  • HelloThread ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ์—์„œ run() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰

  • main ์Šค๋ ˆ๋“œ๋Š” start() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด Thread-n ์Šค๋ ˆ๋“œ์—๊ฒŒ ์‹คํ–‰์„ ์ง€์‹œ

    • main ์Šค๋ ˆ๋“œ๊ฐ€ run() ์„ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ main ์Šค๋ ˆ๋“œ์—์„œ ์ง์ ‘ ์‹คํ–‰

์Šค๋ ˆ๋“œ๋Š” ์ˆœ์„œ์™€ ์‹คํ–‰ ๊ธฐ๊ฐ„์„ ๋ชจ๋‘ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.


Daemon Thread

์Šค๋ ˆ๋“œ๋Š” User Thread, Daemon Thread 2๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๊ตฌ๋ถ„

User Thread(non-daemon Thread)

  • ํ”„๋กœ๊ทธ๋žจ์˜ ์ฃผ์š” ์ž‘์—…์„ ์ˆ˜ํ–‰

  • ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์‹คํ–‰

  • ๋ชจ๋“  user thread๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด JVM๋„ ์ข…๋ฃŒ

Daemon Thread

  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ณด์กฐ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰

  • ๋ชจ๋“  user thread๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด daemon thread๋Š” ์ž๋™์œผ๋กœ ์ข…๋ฃŒ

Daemon Thread


implements Runnable

์‹ค๋ฌด์—์„œ๋Š” ๋ณดํ†ต Runnable์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ

  • ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๊ธฐ์กด๊ณผ ๋™์ผ

  • ์Šค๋ ˆ๋“œ์™€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ํ•  ์ž‘์—…์ด ์„œ๋กœ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋‹ค๋Š” ์ฐจ์ด

    • ์Šค๋ ˆ๋“œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ์‹คํ–‰ํ•  ์ž‘์—…์„ ์ƒ์„ฑ์ž๋กœ ์ „๋‹ฌ

Runnable Thread

Thread ํด๋ž˜์Šค ์ƒ์† ๋ฐฉ์‹

์žฅ์ 

  • ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„: Thread ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ run() ๋ฉ”์„œ๋“œ๋งŒ ์žฌ์ •์˜

๋‹จ์ 

  • ์ƒ์†์˜ ์ œํ•œ: ์ž๋ฐ”๋Š” ๋‹จ์ผ ์ƒ์†๋งŒ์„ ํ—ˆ์šฉ

  • ์œ ์—ฐ์„ฑ ๋ถ€์กฑ: ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋น„ํ•ด ์œ ์—ฐ์„ฑ ๊ฐ์†Œ

Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ ๋ฐฉ์‹

์žฅ์ 

  • ์ƒ์†์˜ ์ž์œ ๋กœ์›€: ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„๋„ ๋ฌธ์ œ์—†์ด ๊ตฌํ˜„ ๊ฐ€๋Šฅ

  • ์ฝ”๋“œ์˜ ๋ถ„๋ฆฌ: ์Šค๋ ˆ๋“œ์™€ ์‹คํ–‰ํ•  ์ž‘์—…์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ

  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์ผํ•œ Runnable ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด ์ž์› ๊ด€๋ฆฌ์— ํšจ์œจ์ 

๋‹จ์ 

  • ์ฝ”๋“œ๊ฐ€ ์•ฝ๊ฐ„ ๋ณต์žก: Runnable ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ Thread ์— ์ „๋‹ฌํ•˜๋Š” ๊ณผ์ •์ด ์ถ”๊ฐ€

Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์ž.

์Šค๋ ˆ๋“œ์™€ ์‹คํ–‰ํ•  ์ž‘์—…์„ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•˜๊ณ , ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ Thread ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ์ƒ์†ํ•˜๋Š” ๋ฐฉ์‹๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ ํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


์Šค๋ ˆ๋“œ ์ œ์–ด์™€ ์ƒ๋ช… ์ฃผ๊ธฐ

์Šค๋ ˆ๋“œ์˜ ๊ธฐ๋ณธ ์ •๋ณด

Thread ํด๋ž˜์Šค๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต

์Šค๋ ˆ๋“œ ๊ธฐ๋ณธ ์ •๋ณด

/** main Thread */
Thread mainThread = Thread.currentThread();
/**
 * Thread[#1,main,5,main]
 * [threadId, threadName, threadPriority, threadGroup]
 */
log("mainThread = " + mainThread);
/**
 * 1
 * ์Šค๋ ˆ๋“œ์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ(๊ฐ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด ์œ ์ผํ•œ ID) โ†’ ID๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํ• ๋‹น๋˜๋ฉฐ, ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์—†๋‹ค
 */
log("mainThread.threadId() = " + mainThread.threadId());
/**
 * main
 * ์Šค๋ ˆ๋“œ์˜ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ
 * ์Šค๋ ˆ๋“œ ID๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š์ง€๋งŒ, ์Šค๋ ˆ๋“œ ์ด๋ฆ„์€ ์ค‘๋ณต๋  ์ˆ˜ ์žˆ๋‹ค.
 */
log("mainThread.getName() = " + mainThread.getName());
/**
 * 5
 * ์Šค๋ ˆ๋“œ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ
 * ์šฐ์„ ์ˆœ์œ„๋Š” 1(๊ฐ€์žฅ ๋‚ฎ์Œ)์—์„œ 10(๊ฐ€์žฅ ๋†’์Œ)๊นŒ์ง€์˜ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ๊ฐ’์€ 5
 * setPriority() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
 * ์šฐ์„ ์ˆœ์œ„๋Š” ์Šค๋ ˆ๋“œ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋ฅผ ์šฐ์„  ์‹คํ–‰ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ. ํ•˜์ง€๋งŒ ์‹ค์ œ ์‹คํ–‰ ์ˆœ์„œ๋Š” JVM ๊ตฌํ˜„๊ณผ ์šด์˜์ฒด์ œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.
 */
log("mainThread.getPriority() = " + mainThread.getPriority());
/**
 * java.lang.ThreadGroup[name=main,maxpri=10]
 * ์Šค๋ ˆ๋“œ๊ฐ€ ์†ํ•œ ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ
 * ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์€ ์Šค๋ ˆ๋“œ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต
 * ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋Š” ๋ถ€๋ชจ ์Šค๋ ˆ๋“œ์™€ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์— ์†ํ•จ
 * ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด์„œ ํŠน์ • ์ž‘์—…(์˜ˆ: ์ผ๊ด„ ์ข…๋ฃŒ, ์šฐ์„ ์ˆœ์œ„ ์„ค์ • ๋“ฑ)์„ ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ
 * 
 * ๋ถ€๋ชจ ์Šค๋ ˆ๋“œ(Parent Thread)
 * ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์˜๋ฏธ
 * ์Šค๋ ˆ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด ์ƒ์„ฑ. ์ด๋Ÿฌํ•œ ์ƒ์„ฑ ๊ด€๊ณ„์—์„œ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์Šค๋ ˆ๋“œ๋Š” ์ƒ์„ฑํ•œ ์Šค๋ ˆ๋“œ๋ฅผ ๋ถ€๋ชจ๋กœ ๊ฐ„์ฃผ
 */
log("mainThread.getThreadGroup() = " + mainThread.getThreadGroup());
/**
 * RUNNABLE
 * ์Šค๋ ˆ๋“œ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ
 * ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์€ Thread.State ์—ด๊ฑฐํ˜•์— ์ •์˜๋œ ์ƒ์ˆ˜ ์ค‘ ํ•˜๋‚˜
 * - NEW: ์Šค๋ ˆ๋“œ๊ฐ€ ์•„์ง ์‹œ์ž‘๋˜์ง€ ์•Š์€ ์ƒํƒœ
 * - RUNNABLE: ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๊ฑฐ๋‚˜ ์‹คํ–‰๋  ์ค€๋น„๊ฐ€ ๋œ ์ƒํƒœ
 * - WAITING: ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ํŠน์ • ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ
 * - TIMED_WAITING: ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ
 * - BLOCKED: ์Šค๋ ˆ๋“œ๊ฐ€ ๋™๊ธฐํ™” ๋ฝ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ์ด
 * - TERMINATED: ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰์„ ๋งˆ์นœ ์ƒํƒœ
 */
log("mainThread.getState() = " + mainThread.getState());

์Šค๋ ˆ๋“œ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ

์Šค๋ ˆ๋“œ๋Š” ์ƒ์„ฑํ•˜๊ณ  ์‹œ์ž‘ํ•˜๊ณ , ์ข…๋ฃŒ๋˜๋Š” ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

โ„น๏ธ New (์ƒˆ๋กœ์šด ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์•„์ง ์‹œ์ž‘๋˜์ง€ ์•Š์€ ์ƒํƒœ

  • Thread ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์ง€๋งŒ start() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ์ƒํƒœ

  • Thread thread = new Thread(runnable);

โ„น๏ธ Runnable (์‹คํ–‰ ๊ฐ€๋Šฅ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋  ์ค€๋น„๊ฐ€ ๋˜์–ด CPU์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ

    • thread.start() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์Šค๋ ˆ๋“œ๋Š” Runnable ์ƒํƒœ๋กœ ์ „์ด

  • Runnable ์ƒํƒœ์— ์žˆ๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

    • ์šด์˜์ฒด์ œ์˜ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ๊ฐ ์Šค๋ ˆ๋“œ์— CPU ์‹œ๊ฐ„์„ ํ• ๋‹นํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์—,

    • Runnable ์ƒํƒœ์— ์žˆ๋Š” ์Šค๋ ˆ๋“œ๋Š” ์Šค์ผ€์ค„๋Ÿฌ์˜ ์‹คํ–‰ ๋Œ€๊ธฐ์—ด์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๊ฐ€ ์ฐจ๋ก€๋กœ CPU์—์„œ ์‹คํ–‰

  • ์šด์˜์ฒด์ œ ์Šค์ผ€์ค„๋Ÿฌ์˜ ์‹คํ–‰ ๋Œ€๊ธฐ์—ด์— ์žˆ๋“ , CPU์—์„œ ์‹ค์ œ ์‹คํ–‰๋˜๊ณ  ์žˆ๋“  ๋ชจ๋‘ RUNNABLE ์ƒํƒœ

    • ์ž๋ฐ”์—์„œ ๋‘˜์„ ๊ตฌ๋ถ„ํ•ด์„œ ํ™•์ธํ•  ์ˆ˜ ์—†์–ด์„œ ๋ณดํ†ต ์‹คํ–‰ ์ƒํƒœ๋ผ๊ณ  ๋ถ€๋ฆ„

โ„น๏ธ Blocked (์ฐจ๋‹จ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด ๋™๊ธฐํ™” ๋ฝ์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ

    • synchronized ๋ธ”๋ก์— ์ง„์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๋ฝ์„ ์–ป์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

โ„น๏ธ Waiting (๋Œ€๊ธฐ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ํŠน์ • ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๋ฌด๊ธฐํ•œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ

    • wait(), join() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ Waiting ์ƒํƒœ๋กœ ์ „์ด

  • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ notify() or notifyAll() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜, join() ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

โ„น๏ธ Timed Waiting (์‹œ๊ฐ„ ์ œํ•œ ๋Œ€๊ธฐ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ํŠน์ • ์‹œ๊ฐ„ ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ

    • sleep(long millis), wait(long timeout), join(long millis) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ Timed Waiting ์ƒํƒœ๋กœ ์ „์ด

  • ์ฃผ์–ด์ง„ ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๋ฉด ์ด ์ƒํƒœ์—์„œ ๋ฒ—์–ด๋‚จ

โ„น๏ธ Terminated (์ข…๋ฃŒ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋œ ์ƒํƒœ

    • ์Šค๋ ˆ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ Terminated ์ƒํƒœ๋กœ ์ „์ด

  • ์Šค๋ ˆ๋“œ๋Š” ํ•œ ๋ฒˆ ์ข…๋ฃŒ๋˜๋ฉด ๋‹ค์‹œ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Œ

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new MyRunnable(), "myThread");
    log("myThread.state1 = " + thread.getState()); // (1) NEW

    log("myThread.start()");
    thread.start();
    Thread.sleep(1000);

    log("myThread.state3 = " + thread.getState()); // (3) TIMED_WAITING (Thread.sleep())
    Thread.sleep(4000);

    log("myThread.state5 = " + thread.getState()); // (5) TERMINATED
    log("end");
}

static class MyRunnable implements Runnable {
    public void run() {
        try {
            log("start");
            log("myThread.state2 = " + Thread.currentThread().getState()); // (2) RUNNABLE

            log("sleep() start");
            Thread.sleep(3000);
            log("sleep() end");

            log("myThread.state4 = " + Thread.currentThread().getState()); // (4) RUNNABLE
            log("end");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

์ฐธ๊ณ . ์ž๋ฐ”์—์„œ ๋ฉ”์„œ๋“œ ์žฌ์ •์˜ ์‹œ, ์žฌ์ •์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ง€์ผœ์•ผํ•  ์˜ˆ์™ธ์™€ ๊ด€๋ จ๋œ ๊ทœ์น™

  • ์ฒดํฌ ์˜ˆ์™ธ

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

    • ์ž์‹ ๋ฉ”์„œ๋“œ๋Š” ๋ถ€๋ชจ ๋ฉ”์„œ๋“œ๊ฐ€ ๋˜์งˆ ์ˆ˜ ์žˆ๋Š” ์ฒดํฌ ์˜ˆ์™ธ์˜ ํ•˜์œ„ ํƒ€์ž…๋งŒ ๋˜์งˆ ์ˆ˜ ์žˆ์Œ

  • ์–ธ์ฒดํฌ(๋Ÿฐํƒ€์ž„) ์˜ˆ์™ธ

    • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ•์ œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ƒ๊ด€์—†์ด ๋˜์งˆ ์ˆ˜ ์žˆ์Œ

run() ๋ฉ”์„œ๋“œ๋Š” ์ฒดํฌ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ์ˆ˜ ์—†๋„๋ก ๊ฐ•์ œํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์ด ๋น„์ •์ƒ ์ข…๋ฃŒ๋˜๋Š” ์ƒํ™ฉ์„ ๋ฐฉ์ง€

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ•์ œํ•จ์œผ๋กœ์จ ์Šค๋ ˆ๋“œ์˜ ์•ˆ์ •์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€

์ตœ๊ทผ์—๋Š” ์ฒดํฌ ์˜ˆ์™ธ๋ณด๋‹ค๋Š” ์–ธ์ฒดํฌ ์˜ˆ์™ธ๋ฅผ ์„ ํ˜ธ

...

โ„น๏ธ Join

join์ด ํ•„์š”ํ•œ ์ƒํ™ฉ

  • ๊ธฐ๋Œ€์™€ ๋‹ค๋ฅด๊ฒŒ ๋‘ ๊ฒฐ๊ณผ ๋ชจ๋‘ 0์ด ๋‚˜์˜จ๋‹ค.

join ์‚ฌ์šฉ

Waiting (๋Œ€๊ธฐ ์ƒํƒœ)

  • ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ํŠน์ • ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๋ฌด๊ธฐํ•œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ

  • join()์„ ํ˜ธ์ถœํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ๋Œ€์ƒ ์Šค๋ ˆ๋“œ๊ฐ€ TERMINATED ์ƒํƒœ๊ฐ€ ๋  ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐ

    • ๋Œ€์ƒ ์Šค๋ ˆ๋“œ๊ฐ€ TERMINATED ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๋Š” ๋‹ค์‹œ RUNNABLE ์ƒํƒœ๊ฐ€ ๋˜๋ฉด์„œ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰

ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด join() ์„ ์‚ฌ์šฉํ•˜์ž.

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ž‘์—…์„ ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ๋งŒ ๊ธฐ๋‹ค๋ฆด ๊ฒฝ์šฐ

  • join() : ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๋Š” ๋Œ€์ƒ ์Šค๋ ˆ๋“œ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ ๊นŒ์ง€ ๋ฌดํ•œ์ • ๋Œ€๊ธฐ

  • join(ms) : ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๋Š” ํŠน์ • ์‹œ๊ฐ„ ๋งŒํผ๋งŒ ๋Œ€๊ธฐ

    • ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๋Š” ์ง€์ •ํ•œ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋‹ค์‹œ RUNNABLE ์ƒํƒœ๊ฐ€ ๋˜๋ฉด์„œ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰

...

โ„น๏ธ Interrupt

์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด WAITING, TIMED_WAITING ๊ฐ™์€ ๋Œ€๊ธฐ ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ง์ ‘ ๊นจ์›Œ์„œ,

์ž‘๋™ํ•˜๋Š” RUNNABLE ์ƒํƒœ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ์ผ ๋•Œ

  • InterruptedException ์„ ๋˜์ง€๋Š” ๋ฉ”์„œ๋“œ(ex. Thread.sleep())๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜

  • ์ด๋ฏธ ์œ„ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋Œ€๊ธฐ์ค‘์ด๋ผ๋ฉด InterruptedException ๋ฐœ์ƒ

Thread.currentThread().isInterrupted()

  • ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ ๋‹จ์ˆœํžˆ ํ™•์ธ

Thread.interrupted()

  • ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ง์ ‘ ์ฒดํฌํ•ด์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ

    • ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ์ผ ๊ฒฝ์šฐ, true ๋ฐ˜ํ™˜ ํ›„ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ false ๋กœ ๋ณ€๊ฒฝ

    • ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ, false ๋ฐ˜ํ™˜ ํ›„ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ

thread.interrupted()

์ธํ„ฐ๋ŸฝํŠธ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ ์ •์ƒ(false)์œผ๋กœ ๋Œ๋ฆฌ์ง€ ์•Š์œผ๋ฉด, ์ดํ›„์—๋„ ๊ณ„์† ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒ

๊ทธ๋Ÿฌ๋ฏ€๋กœ, ์ž๋ฐ”์—์„œ ์ธํ„ฐ๋ŸฝํŠธ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์ธํ„ฐ๋ŸฝํŠธ์˜ ๋ชฉ์ ์„ ๋‹ฌ์„ฑํ•˜๋ฉด, ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ ๋‹ค์‹œ ์ •์ƒ(false)์œผ๋กœ ๋Œ๋ฆฐ๋‹ค.

  • InterruptedException

  • Thread.interrupted()

ํ”„๋ฆฐํ„ฐ ์˜ˆ์ œ

  • ์‹œ์ž‘

    • ์ข…๋ฃŒ ์ž…๋ ฅ ์‹œ ๋ฐ”๋กœ ๋ฐ˜์‘ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ

  • ์ธํ„ฐ๋ŸฝํŠธ ๋„์ž…

    • ์ข…๋ฃŒ(q)๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ฆ‰์‹œ ์ข…๋ฃŒ

  • ์ธํ„ฐ๋ŸฝํŠธ ๊ฐœ์„ 

    • Thread.interrupted() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ์ธ์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๊ณ , ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐ๋ŸฝํŠธ ์ƒํƒœ๋ฅผ ๋‹ค์‹œ ์ •์ƒ์œผ๋กœ ์ „ํ™˜

  • yield๋ฅผ ํ™œ์šฉํ•œ CPU ์ž์› ์–‘๋ณด

    • ์ž‘์—…์ด ๋น„์–ด์žˆ์œผ๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์ž‘์—…์„ ์–‘๋ณด

...

โ„น๏ธ Yield

ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž๋ฐœ์ ์œผ๋กœ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ CPU๋ฅผ ์–‘๋ณด

yield() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ๋Š” RUNNABLE ์ƒํƒœ๋ฅผ ์œ ์ง€

์ž๋ฐ”์—์„œ Thread.yield() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ CPU๋ฅผ ์–‘๋ณดํ•˜๋„๋ก ํžŒํŠธ ์ œ๊ณต

  • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์‹คํ–‰ ๊ธฐํšŒ๋ฅผ ์ œ๊ณต

  • RUNNABLE ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์–‘๋ณดํ•  ์Šค๋ ˆ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด ๋ณธ์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์† ์‹คํ–‰

Thread.yield() Example

...

โ„น๏ธ volatile

๋ฉ”๋ชจ๋ฆฌ ๊ฐ€์‹œ์„ฑ(memory visibility)

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ€๊ฒฝํ•œ ๊ฐ’์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์–ธ์ œ ๋ณด์ด๋Š”์ง€์— ๋Œ€ํ•œ ๋ฌธ์ œ

์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ๋ณ€๊ฒฝํ•œ ๊ฐ’์ด ๋ณด์ด๋Š”๊ฐ€, ๋ณด์ด์ง€ ์•Š๋Š”๊ฐ€์˜ ๋ฌธ์ œ

๋ฉ”๋ชจ๋ฆฌ ๊ฐ€์‹œ์„ฑ(memory visibility) ๋ฌธ์ œ

  • ์Šค๋ ˆ๋“œ๊ฐ€ while ๋ฌธ์—์„œ ๋น ์ ธ๋‚˜์˜ค์ง€ ๋ชปํ•˜๊ณ  ๊ณ„์† ์‹คํ–‰ ์ƒํƒœ

CPU์™€ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์ด ๋Œ€ํ•˜์—ฌ / ํŽผ์น˜๊ธฐ

...

CPU ๋Š” ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ ๊ฐœ์„ ์„ ์œ„ํ•ด ์ค‘๊ฐ„์— ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉ

๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ

  • CPU์—์„œ ๊ฐ€๊นŒ์šด ๊ฑฐ๋ฆฌ์— ์œ„์น˜

  • CPU์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆฐ ์†๋„

  • CPU์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ์ €๋ ดํ•œ ๊ฐ€๊ฒฉ

์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ

  • CPU์™€ ๊ฐ€๊นŒ์ด์šด ๊ฑฐ๋ฆฌ์— ์œ„์น˜

  • ๋งค์šฐ ๋น ๋ฅธ ์†๋„์˜ ๋ฉ”๋ชจ๋ฆฌ

  • ์ƒ๋Œ€์ ์œผ๋กœ ๋น„์‹ผ ๊ฐ€๊ฒฉ

์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ’์„ ๋ณด๊ด€

  • ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ flag ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด CPU๋Š” ์ด ๊ฐ’์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋ณด๊ด€

  • ์ดํ›„๋ถ€ํ„ฐ๋Š” ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” flag ์‚ฌ์šฉ

main ์Šค๋ ˆ๋“œ์—์„œ flag ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๊ฒฝ์šฐ

  • main ์Šค๋ ˆ๋“œ์—์„œ flag ๊ฐ’ ๋ณ€๊ฒฝ ์‹œ CPU ์ฝ”์–ด 1์ด ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ flag ๊ฐ’๋งŒ ๋ณ€ํ•จ

    • ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ด ๊ฐ’์ด ์ฆ‰์‹œ ๋ฐ˜์˜๋˜์ง€ ์•Š์Œ

  • work ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” CPU ์ฝ”์–ด2์˜ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ flag ๊ฐ’์€ ์—ฌ์ „ํžˆ true

์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” ๊ฐ’์ด ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜์˜๋˜๋Š” ์‹œ๊ธฐ

  • CPU ์ฝ”์–ด 1์˜ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” flag ๊ฐ’์ด ์–ธ์ œ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜์˜๋ ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๋‹ค.

    • CPU ์„ค๊ณ„ ๋ฐฉ์‹๊ณผ ์ข…๋ฅ˜์˜ ๋”ฐ๋ผ ๋‹ค๋ฅด๊ณ  ๊ทน๋‹จ์ ์œผ๋กœ ๋ณด๋ฉด ํ‰์ƒ ๋ฐ˜์˜๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ

  • ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜์˜์„ ํ•œ๋‹ค๊ณ  ํ•ด๋„, CPU ์ฝ”์–ด 2์˜ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์–ธ์ œ ๋ฐ˜์˜๋ ์ง€๋„ ์•Œ ์ˆ˜ ์—†๋‹ค.

์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜์˜ํ•˜๊ฑฐ๋‚˜, ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ณ€๊ฒฝ ๋‚ด์—ญ์„ ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์‹œ๊ธฐ

  • CPU ์„ค๊ณ„ ๋ฐฉ์‹๊ณผ ์‹คํ–‰ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ

    • ์ฆ‰์‹œ, ๋ช‡ ๋ฐ€๋ฆฌ์ดˆ ํ›„, ๋ช‡ ์ดˆ ํ›„, ํ‰์ƒ ๋ฐ˜์˜๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ

  • ์ฃผ๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋  ๋•Œ, ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋„ ํ•จ๊ป˜ ๊ฐฑ์‹ ๋˜๋Š”๋ฐ, ์ด ๋ถ€๋ถ„๋„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ

    • ex. Thread.sleep(), Syste.out ์‹œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž ์‹œ ์‰ฌ๋Š”๋ฐ, ์ด๋Ÿด ๋•Œ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋˜๋ฉด์„œ ์ฃผ๋กœ ๊ฐฑ์‹ 

Example

.

volatile

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ™์€ ๊ฐ’์„ ์ฝ๊ณ  ์จ์•ผ ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋Š” ํ‚ค์›Œ๋“œ

  • ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด CPU ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜์ง€๋งŒ, ๋•Œ๋กœ๋Š” ์„ฑ๋Šฅ ํ–ฅ์ƒ๋ณด๋‹ค ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ™์€ ์‹œ์ ์— ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Œ

  • ์ด ๊ฒฝ์šฐ, ์„ฑ๋Šฅ์„ ์•ฝ๊ฐ„ ํฌ๊ธฐํ•˜๋Š” ๋Œ€์‹  ๊ฐ’์„ ์ฝ๊ณ  ์“ธ ๋•Œ ๋ชจ๋‘ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋„๋ก ์ž๋ฐ”์—์„œ๋Š” volatile ํ‚ค์›Œ๋“œ ์ œ๊ณต

volatile ํ‚ค์›Œ๋“œ ์ ์šฉ


Java Memory Model

โ„น๏ธ ๋ฉ”๋ชจ๋ฆฌ ๊ฐ€์‹œ์„ฑ(memory visibility)

  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ€๊ฒฝํ•œ ๊ฐ’์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์–ธ์ œ ๋ณด์ด๋Š”์ง€์— ๋Œ€ํ•œ ๊ฒƒ

  • ๋ฉ”๋ชจ๋ฆฌ์— ๋ณ€๊ฒฝํ•œ ๊ฐ’์ด ๋ณด์ด๋Š”๊ฐ€, ๋ณด์ด์ง€ ์•Š๋Š”๊ฐ€์˜ ๋ฌธ์ œ

...

โ„น๏ธ Java Memory Model

  • Java Memory Model(JMM)์€ ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋–ป๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ทœ์ •

  • ํŠนํžˆ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ •์˜

  • ํ•ต์‹ฌ์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋“ค์˜ ์ž‘์—… ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๋Š” happens-before ๊ด€๊ณ„์— ๋Œ€ํ•œ ์ •์˜

...

โ„น๏ธ happens-before

  • Java Memory Model(JMM)์—์„œ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์ž‘์—… ์ˆœ์„œ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐœ๋…

  • ํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰ํ•œ ์ž‘์—…์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฐธ์กฐํ•  ๋•Œ ์ตœ์‹  ์ƒํƒœ๊ฐ€ ๋ณด์žฅ

  • ex. A ์ž‘์—…์—์„œ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์€ B ์ž‘์—…์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ˜์˜

.

happens-before ๊ด€๊ณ„๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ

  • ํ”„๋กœ๊ทธ๋žจ ์ˆœ์„œ ๊ทœ์น™

  • volatile ๋ณ€์ˆ˜ ๊ทœ์น™

  • ์Šค๋ ˆ๋“œ ์‹œ์ž‘/์ข…๋ฃŒ/์ธํ„ฐ๋ŸฝํŠธ ๊ทœ์น™

  • ๊ฐ์ฒด ์ƒ์„ฑ ๊ทœ์น™

  • ๋ชจ๋‹ˆํ„ฐ ๋ฝ ๊ทœ์น™

  • ์ „์ด ๊ทœ์น™

  • ...

volatile ๋˜๋Š” ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•(synchronized, ReentrantLock ..)์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๊ฐ€์‹œ์„ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค


synchronized

์ž๋ฐ”์—์„œ ๋™๊ธฐํ™”(synchronization)๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ž์›(์˜ˆ: ๊ฐ์ฒด, ๋ฉ”์„œ๋“œ)์— ๋Œ€ํ•ด ์ผ๊ด€์„ฑ ์žˆ๊ณ  ์•ˆ์ „ํ•œ ์ ‘๊ทผ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜

๋™๊ธฐํ™”๋Š” ์ฃผ๋กœ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ(๋ฐ์ดํ„ฐ ์†์ƒ์ด๋‚˜ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๊ฒฐ๊ณผ)๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

  • ์ž๋ฐ”๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ ๋ คํ•˜๊ณ  ๋‚˜์˜จ ์–ธ์–ด๋กœ JDK 1.0 ๋ถ€ํ„ฐ synchronized ๊ฐ™์€ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ๋ฌธ๋ฒ•์— ํฌํ•จํ•ด์„œ ์ œ๊ณต

์žฅ์ .

  • ํŽธ๋ฆฌํ•จ: ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋ฌธ๋ฒ•์œผ๋กœ ์ œ๊ณตํ•˜์—ฌ ํŽธ๋ฆฌํ•œ ์‚ฌ์šฉ

  • ์ž๋™ ์ž ๊ธˆ ํ•ด์ œ: synchronized ๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์ด ์™„๋ฃŒ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋ฝ์„ ๋Œ€๊ธฐ์ค‘์ธ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ž ๊ธˆ์ด ํ•ด์ œ

    • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํŠน์ • ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๋„๋ก ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋งค์šฐ ์–ด๋ ต๊ณ  ๋ฒˆ๊ฑฐ๋กœ์›€

๋‹จ์ 

  • ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ: ํŽธ๋ฆฌํ•˜์ง€๋งŒ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด ๋„ˆ๋ฌด ๋‹จ์ˆœ

  • ๋ฌดํ•œ ๋Œ€๊ธฐ: BLOCKED ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์ด ํ’€๋ฆด ๋•Œ ๊นŒ์ง€ ๋ฌดํ•œ ๋Œ€๊ธฐ

    • ํƒ€์ž„์•„์›ƒ์ด๋‚˜ ์ค‘๊ฐ„์— ์ธํ„ฐ๋ŸฝํŠธ ๋ถˆ๊ฐ€

  • ๊ณต์ •์„ฑ: ๋ฝ์ด ๋Œ์•„์™”์„ ๋•Œ BLOCKED ์ƒํƒœ์˜ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ์ค‘์— ์–ด๋–ค ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ํ•  ์ง€ ์•Œ ์ˆ˜ ์—†์Œ

๋” ์œ ์—ฐํ•˜๊ณ , ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•๋“ค์ด ํ•„์š”ํ•˜๊ฒŒ ๋˜์–ด JDK 1.5 ๋ถ€ํ„ฐ ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ java.util.concurrent ํŒจํ‚ค์ง€๊ฐ€ ์ถ”๊ฐ€

Concurrency Issue

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€, ๊ฐ™์€ ์ž์›(๋ฆฌ์†Œ์Šค)์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋™์‹œ์„ฑ ๋ฌธ์ œ

  • ๊ณต์œ  ์ž์›: ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•˜๋Š” ์ž์›

    • ๋Œ€ํ‘œ์ ์ธ ๊ณต์œ  ์ž์›์€ ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)

  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์‚ฌ์šฉ ์‹œ ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ ์ ˆํ•˜๊ฒŒ ๋™๊ธฐํ™”(synchronization)ํ•ด์„œ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”

์ถœ๊ธˆ ์˜ˆ์ œ ๋™์‹œ์„ฑ ๋ฌธ์ œ

...

โ„น๏ธ ์ž„๊ณ„ ์˜์—ญ(critical section)

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๋‚˜ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜ํ•˜๊ณ , ์ค‘์š”ํ•œ ์ฝ”๋“œ

  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ๋Š” ์•ˆ ๋˜๋Š” ๊ณต์œ  ์ž์›์„ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ๋ถ€๋ถ„

    • ex. ๊ณต์œ  ๋ณ€์ˆ˜๋‚˜ ๊ณต์œ  ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •

  • ์ž„๊ณ„ ์˜์—ญ์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ˆ์ „ํ•˜๊ฒŒ ๋ณดํ˜ธ๊ฐ€ ํ•„์š”

  • ์ž๋ฐ”๋Š” synchronized ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž„๊ณ„ ์˜์—ญ์„ ๋ณดํ˜ธ


synchronized method

๋ฉ”์„œ๋“œ๋ฅผ synchronized ๋กœ ์„ ์–ธํ•ด์„œ, ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜๋ฟ์ด๋„๋ก ๋ณด์žฅ

public synchronized void synchronizedMethod() {
    // something
}
  • ๋ชจ๋“  ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋Š” ๋‚ด๋ถ€์— ์ž์‹ ๋งŒ์˜ ๋ฝ(lock)์„ ๋ณด์œ 

    • aka. ๋ชจ๋‹ˆํ„ฐ ๋ฝ(monitor lock)

    • ๊ฐ์ฒด ๋‚ด๋ถ€์— ์žˆ๋‹ค๋ณด๋‹ˆ ํ™•์ธํ•˜๊ธฐ๋Š” ์–ด๋ ค์›€

  • ์Šค๋ ˆ๋“œ๊ฐ€ synchronized ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ๋Š” ๋ฉ”์„œ๋“œ์— ์ง„์ž…ํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ํ•ด๋‹น ์ธ์Šคํ„ด์Šค์˜ ๋ฝ์ด ํ•„์š”

    • (thread1) synchronized ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ๋ฝ ํš๋“ ์‹œ๋„

    • (thread2) ๋ฝ์ด ์—†์„ ๊ฒฝ์šฐ ํš๋“ํ•  ๋•Œ๊นŒ์ง€ BLOCKED ์ƒํƒœ๋กœ ๋Œ€๊ธฐ

    • (thread1) ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ๋๋‚˜๋ฉด ๋ฝ์„ ๋ฐ˜๋‚ฉ

    • (thread2) ๋ฝ ํš๋“์„ ๋Œ€๊ธฐํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ์ž๋™์œผ๋กœ ๋ฝ์„ ํš๋“

  • ์ฐธ๊ณ ) ๋ฝ์„ ํš๋“ํ•˜๋Š” ์ˆœ์„œ๋Š” ๋ณด์žฅ๋˜์ง€ ์•Š์Œ

  • ์ฐธ๊ณ ) ์ž๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ๊ฐ€์‹œ์„ฑ ๋ฌธ์ œ๋Š” ์ž๋™์œผ๋กœ ํ•ด๊ฒฐ

synchronized method ์ ์šฉ


synchronized code block

์ฝ”๋“œ ๋ธ”๋ก์„ synchronized ๋กœ ๊ฐ์‹ธ์„œ, ๋™๊ธฐํ™”๋ฅผ ๊ตฌํ˜„

public void method() {
    synchronized(this) {
        // synchronized code
    }
}
  • synchronized ์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด์ž ๋‹จ์ ์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ 

  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ „์ฒด๋กœ ๋ณด๋ฉด ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Œ

  • ๋”ฐ๋ผ์„œ synchronized ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ ๊ตฌ๊ฐ„์€ ๊ผญ ํ•„์š”ํ•œ ๊ณณ์œผ๋กœ ํ•œ์ •ํ•ด์„œ ์„ค์ •์ด ํ•„์š”

    • synchronized code block์œผ๋กœ ํ•„์š”ํ•œ ๋ถ€๋ถ„์— ์ž„๊ณ„ ์˜์—ญ์„ ์ง€์ • ๊ฐ€๋Šฅ

    • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ˆ˜ํ–‰๋˜๋Š” ๋ถ€๋ถ„์„ ๋” ๋Š˜๋ ค์„œ, ์ „์ฒด์ ์œผ๋กœ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ

synchronized code block ์ ์šฉ

...

๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค

  • ๊ฒฝํ•ฉ ์กฐ๊ฑด(Race condition)

    • ๋‘ ๊ฐœ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฒฝ์Ÿ์ ์œผ๋กœ ๋™์ผํ•œ ์ž์›์„ ์ˆ˜์ •ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

  • ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ

    • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ฝ๊ณ , ์“ฐ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€

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

      • ๊ผญ ํ•„์š”ํ•œ ๊ณณ์— ์ ์ ˆํžˆ ์‚ฌ์šฉ ํ•„์š”


concurrent.Lock

LockSupport

LockSupport ์€ ReentrantLock ์—์„œ ํ™œ์šฉ๋˜์–ด synchronized ์˜ ๋‹จ์ ์„ ๊ทน๋ณตํ•˜๋ฉด์„œ๋„

๋งค์šฐ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ž„๊ณ„ ์˜์—ญ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ์ œ๊ณต

์ž๋ฐ” 1.0๋ถ€ํ„ฐ ์กด์žฌํ•œ synchronized ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋” ์œ ์—ฐํ•˜๊ณ , ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•๋“ค์ด ํ•„์š”

  • ์ž๋ฐ” 1.5๋ถ€ํ„ฐ java.util.concurrent ๋ผ๋Š” ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒจํ‚ค์ง€๊ฐ€ ์ถ”๊ฐ€

.

synchronized ๋‹จ์ 

  • ๋ฌดํ•œ ๋Œ€๊ธฐ: BLOCKED ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์ด ํ’€๋ฆด ๋•Œ ๊นŒ์ง€ ๋ฌดํ•œ ๋Œ€๊ธฐ

    • ํŠน์ • ์‹œ๊ฐ„๊นŒ์ง€๋งŒ ๋Œ€๊ธฐํ•˜๋Š” ํƒ€์ž„์•„์›ƒ ๋ถˆ๊ฐ€

      • โ†’ LockSupport.parkNanos() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ์‹œ๊ฐ„๊นŒ์ง€๋งŒ ๋Œ€๊ธฐ ๊ฐ€๋Šฅ

    • ์ค‘๊ฐ„์— ์ธํ„ฐ๋ŸฝํŠธ ๋ถˆ๊ฐ€

      • โ†’ park(), parkNanos() ๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ฑธ ์ˆ˜ ์žˆ์Œ

  • ๊ณต์ •์„ฑ: ๋ฝ์ด ๋Œ์•„์™”์„ ๋•Œ BLOCKED ์ƒํƒœ์˜ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ์ค‘์— ์–ด๋–ค ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ํ•  ์ง€ ์•Œ ์ˆ˜ ์—†์Œ

    • ์ตœ์•…์˜ ๊ฒฝ์šฐ ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ๋„ˆ๋ฌด ์˜ค๋žœ๊ธฐ๊ฐ„ ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Œ

.

LockSupport ๋Œ€ํ‘œ ๊ธฐ๋Šฅ

  • park() : ์Šค๋ ˆ๋“œ๋ฅผ WAITING ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

    • ๋ˆ„๊ฐ€ ๊นจ์›Œ์ฃผ๊ธฐ ์ „๊นŒ์ง€๋Š” ๊ณ„์† ๋Œ€๊ธฐ

    • CPU ์‹คํ–‰ ์Šค์ผ€์ค„๋ง์— ๋“ค์–ด๊ฐ€์ง€ ์•Š์Œ

  • parkNanos(nanos) : ์Šค๋ ˆ๋“œ๋ฅผ ๋‚˜๋…ธ์ดˆ ๋™์•ˆ๋งŒ TIMED_WAITING ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

    • ์ง€์ •ํ•œ ๋‚˜๋…ธ์ดˆ๊ฐ€ ์ง€๋‚˜๋ฉด TIMED_WAITING ์ƒํƒœ์—์„œ ๋น ์ ธ๋‚˜์˜ค๊ณ  RUNNABLE ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

  • unpark(thread) : WAITING ์ƒํƒœ์˜ ๋Œ€์ƒ ์Šค๋ ˆ๋“œ๋ฅผ RUNNABLE ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

LockSupport.unpark example LockSupport.parkNanos(nanos) example

...

โ„น๏ธ BLOCKED vs WAITING

BLOCKED , WAITING , TIMED_WAITING ์ƒํƒœ ๋ชจ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐ

  • ์‹คํ–‰ ์Šค์ผ€์ค„๋ง์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, CPU ์ž…์žฅ์—์„œ ๋ณด๋ฉด ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ๋น„์Šทํ•œ ์ƒํƒœ

BLOCKED ์ƒํƒœ

  • synchronized ์—์„œ ๋ฝ์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐํ•  ๋•Œ ์‚ฌ์šฉ

    • synchronized ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋Œ€๊ธฐ ์ƒํƒœ

  • ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๊ฑธ๋ ค๋„ ๋Œ€๊ธฐ ์ƒํƒœ๋ฅผ ๋น ์ ธ๋‚˜์˜ค์ง€ ๋ชปํ•จ

WAITING, TIMED_WAITING ์ƒํƒœ

  • ๋ฒ”์šฉ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€๊ธฐ ์ƒํƒœ

  • ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๊ฑธ๋ฆฌ๋ฉด ๋Œ€๊ธฐ ์ƒํƒœ๋ฅผ ๋น ์ ธ๋‚˜์˜ค๊ณ , RUNNABLE ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

  • ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ

    • Thread.join() , Thread.join(long millis)

    • Thread.park() , Thread.parkNanos(long millis)

    • Object.wait() , Object.wait(long timeout)


ReentrantLock

synchronized ์™€ BLOCKED ์ƒํƒœ๋ฅผ ํ†ตํ•œ ํ†ตํ•œ ์ž„๊ณ„ ์˜์—ญ ๊ด€๋ฆฌ์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด

์ž๋ฐ” 1.5๋ถ€ํ„ฐ Lock ์ธํ„ฐํŽ˜์ด์Šค์™€ ReentrantLock ๊ตฌํ˜„์ฒด๋ฅผ ์ œ๊ณต

์ฐธ๊ณ . ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฝ์€ ๊ฐ์ฒด ๋‚ด๋ถ€์— ์žˆ๋Š” ๋ชจ๋‹ˆํ„ฐ ๋ฝ์ด ์•„๋‹˜

  • Lock ์ธํ„ฐํŽ˜์ด์Šค์™€ ReentrantLock ์ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ

  • ๋ชจ๋‹ˆํ„ฐ ๋ฝ๊ณผ BLOCKED ์ƒํƒœ๋Š” synchronized ์—์„œ๋งŒ ์‚ฌ์šฉ

...

โ„น๏ธ Lock Interface

  • ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์“ฐ์ด๋Š” ์•ˆ์ „ํ•œ ์ž„๊ณ„ ์˜์—ญ์„ ์œ„ํ•œ ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

    • synchronized ์˜ ๋‹จ์ ์ธ ๋ฌดํ•œ ๋Œ€๊ธฐ ๋ฌธ์ œ ํ•ด๊ฒฐ

  • ๊ณ ์ˆ˜์ค€์˜ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์„ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

    • ๋ฝ์„ ํŠน์ • ์‹œ๊ฐ„ ๋งŒํผ๋งŒ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜, ์ธํ„ฐ๋ŸฝํŠธ ๊ฐ€๋Šฅํ•œ ๋ฝ์„ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉ

    • ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋‹ค์–‘ํ•œ ์„ ํƒ๊ถŒ์„ ์ œ๊ณต

  • ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด๋กœ ReentrantLock

public interface Lock {
    /** 
     * ๋ฝ์„ ํš๋“
     * - ๋งŒ์•ฝ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ ๋ฝ์„ ํš๋“ํ–ˆ๋‹ค๋ฉด, ๋ฝ์ด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋Š” WAITING
     * - ์ธํ„ฐ๋ŸฝํŠธ์— ์‘๋‹ตํ•˜์ง€ ์•Š์Œ
     */
    void lock();
    /**
     * ๋ฝ ํš๋“์„ ์‹œ๋„ํ•˜๋˜, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
     * - ๋งŒ์•ฝ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ ๋ฝ์„ ํš๋“ํ–ˆ๋‹ค๋ฉด, ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์„ ํš๋“ํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
     * - ๋Œ€๊ธฐ ์ค‘์— ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด InterruptedException ์ด ๋ฐœ์ƒํ•˜๋ฉฐ ๋ฝ ํš๋“์„ ํฌ๊ธฐ
     */
    void lockInterruptibly() throws InterruptedException;
    /**
     * ํš๋“์„ ์‹œ๋„ํ•˜๊ณ , ์ฆ‰์‹œ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
     * - ๋งŒ์•ฝ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฏธ ๋ฝ์„ ํš๋“ํ–ˆ๋‹ค๋ฉด false ๋ฐ˜ํ™˜
     * - ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฝ์„ ํš๋“ํ•˜๊ณ  true ๋ฐ˜ํ™˜
     */
    boolean tryLock();
    /**
     * ์ฃผ์–ด์ง„ ์‹œ๊ฐ„ ๋™์•ˆ ๋ฝ ํš๋“ ์‹œ๋„
     * - ์ฃผ์–ด์ง„ ์‹œ๊ฐ„ ์•ˆ์— ๋ฝ์„ ํš๋“ํ•˜๋ฉด true ๋ฐ˜ํ™˜
     * - ์ฃผ์–ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋„ ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜
     * - ๋Œ€๊ธฐ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด InterruptedException ์ด ๋ฐœ์ƒํ•˜๋ฉฐ ๋ฝ ํš๋“์„ ํฌ๊ธฐ
     */
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    /**
     * ๋ฝ์„ ํ•ด์ œ
     * - ๋ฝ์„ ํ•ด์ œํ•˜๋ฉด ๋ฝ ํš๋“์„ ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฝ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
     * - ๋ฝ์„ ํš๋“ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฉฐ
     * - ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด IllegalMonitorStateException ๋ฐœ์ƒ
     */
    void unlock();
    /**
     * Condition ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜
     * - Condition ๊ฐ์ฒด๋Š” ๋ฝ๊ณผ ๊ฒฐํ•ฉ๋˜์–ด ์‚ฌ์šฉ
     * - ์Šค๋ ˆ๋“œ๊ฐ€ ํŠน์ • ์กฐ๊ฑด์„ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ์‹ ํ˜ธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•จ
     * - Object.wait(), notify(), notifyAll() ๋ฉ”์„œ๋“œ์™€ ์œ ์‚ฌํ•œ ์—ญํ• 
     */
    Condition newCondition();
}

...

โ„น๏ธ ๊ณต์ •์„ฑ

Lock ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด ReentrantLock ํด๋ž˜์Šค๋Š”

์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์ •ํ•˜๊ฒŒ ๋ฝ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“œ๋ฅผ ์ œ๊ณต

ReentrantLock ๋ฝ์€ ๊ณต์ •์„ฑ(fairness) ๋ชจ๋“œ์™€ ๋น„๊ณต์ •(non-fair) ๋ชจ๋“œ๋กœ ์„ค์ • ๊ฐ€๋Šฅ

  • ์ด ๋‘ ๋ชจ๋“œ๋Š” ๋ฝ์„ ํš๋“ํ•˜๋Š” ๋ฐฉ์‹์—์„œ ์ฐจ์ด

.

๋น„๊ณต์ • ๋ชจ๋“œ(Non-fair mode)

  • ReentrantLock ์˜ ๊ธฐ๋ณธ ๋ชจ๋“œ

  • ๋ฝ์„ ๋จผ์ € ์š”์ฒญํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ๋จผ์ € ํš๋“ํ•œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†์Œ

    • ๋ฝ์„ ํ’€์—ˆ์„ ๋•Œ, ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ์•„๋ฌด๋‚˜ ๋ฝ์„ ํš๋“

    • ๋ฝ์„ ๋นจ๋ฆฌ ํš๋“ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ์žฅ๊ธฐ๊ฐ„ ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ์กด์žฌ

    • ๊ทธ๋ž˜๋„, ๋‚ด๋ถ€์—์„œ ํ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—

      • ์Šค๋ ˆ๋“œ ๊ฒฝํ•ฉ์ด ์‹ฌํ•  ๋•Œ ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€๋” ๋ช‡ ๊ฐœ์”ฉ ๋จผ์ € ์‹คํ–‰๋˜๋Š” ์ •๋„

๋น„๊ณต์ • ๋ชจ๋“œ ํŠน์ง•

  • ์„ฑ๋Šฅ ์šฐ์„ : ๋ฝ์„ ํš๋“ ์†๋„๊ฐ€ ๋น ๋ฆ„

  • ์„ ์  ๊ฐ€๋Šฅ: ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๊ฐ€ ๊ธฐ์กด ๋Œ€๊ธฐ ์Šค๋ ˆ๋“œ๋ณด๋‹ค ๋จผ์ € ๋ฝ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Œ

  • ๊ธฐ์•„ ํ˜„์ƒ ๊ฐ€๋Šฅ์„ฑ: ํŠน์ • ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์†ํ•ด์„œ ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Œ

.

๊ณต์ • ๋ชจ๋“œ(Fair mode)

  • ๋ฝ์„ ์š”์ฒญํ•œ ์ˆœ์„œ๋Œ€๋กœ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“

  • ๋จผ์ € ๋Œ€๊ธฐํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋จผ์ € ๋ฝ์„ ํš๋“ํ•˜๊ฒŒ ๋˜์–ด ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ๊ณต์ •์„ฑ์„ ๋ณด์žฅ

    • ๊ทธ๋Ÿฌ๋‚˜ ์ด๋กœ ์ธํ•ด ์„ฑ๋Šฅ ์ €ํ•˜

๊ณต์ • ๋ชจ๋“œ ํŠน์ง•

  • ๊ณต์ •์„ฑ ๋ณด์žฅ: ๋Œ€๊ธฐ ํ์—์„œ ๋จผ์ € ๋Œ€๊ธฐํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ๋จผ์ € ํš๋“

  • ๊ธฐ์•„ ํ˜„์ƒ ๋ฐฉ์ง€: ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์–ธ์  ๊ฐ€ ๋ฝ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณด์žฅ

  • ์„ฑ๋Šฅ ์ €ํ•˜: ์šฐ์„ ์ˆ˜์œ„ ์„ ์ •์„ ์œ„ํ•ด ๋ฝ์„ ํš๋“ํ•˜๋Š” ์†๋„๊ฐ€ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์Œ

ReentrantLock fair mode example


์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ

์ƒ์‚ฐ์ž(Producer)

  • ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• 

  • ex. ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ฑฐ๋‚˜ ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์Šค๋ ˆ๋“œ

์†Œ๋น„์ž(Consumer)

  • ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์—ญํ• 

  • ex. ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜๋Š” ์Šค๋ ˆ๋“œs

๋ฒ„ํผ(Buffer)

  • ์ƒ์‚ฐ์ž๊ฐ€ ์ƒ์„ฑํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„

  • ํ•œ์ •๋œ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž๊ฐ€ ์ด ๋ฒ„ํผ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์Œ

.

์ƒ์‚ฐ์ž/์†Œ๋น„์ž ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ

์ƒ์‚ฐ์ž๊ฐ€ ๋„ˆ๋ฌด ๋น ๋ฅผ ๋•Œ

  • ๋ฒ„ํผ๊ฐ€ ๊ฐ€๋“ ์ฐจ์„œ ๋” ์ด์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ์ƒ์‚ฐ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ

  • ๋ฒ„ํผ๊ฐ€ ๊ฐ€๋“ ์ฐฌ ๊ฒฝ์šฐ ์ƒ์‚ฐ์ž๋Š” ๋ฒ„ํผ์— ๋นˆ ๊ณต๊ฐ„์ด ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

์†Œ๋น„์ž๊ฐ€ ๋„ˆ๋ฌด ๋น ๋ฅผ ๋•Œ

  • ๋ฒ„ํผ๊ฐ€ ๋น„์–ด์„œ ๋” ์ด์ƒ ์†Œ๋น„ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ์†Œ๋น„์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ

  • ๋ฒ„ํผ๊ฐ€ ๋น„์–ด์žˆ์„ ๋•Œ ์†Œ๋น„์ž๋Š” ๋ฒ„ํผ์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

.

์ƒ์‚ฐ์ž-์†Œ๋น„์ž ๋ฌธ์ œ(producer-consumer problem)

  • ์ƒ์‚ฐ์ž-์†Œ๋น„์ž ๋ฌธ์ œ๋Š”, ์ƒ์‚ฐ์ž ์Šค๋ ˆ๋“œ์™€ ์†Œ๋น„์ž ์Šค๋ ˆ๋“œ๊ฐ€ ํŠน์ • ์ž์›์„ ํ•จ๊ป˜ ์ƒ์‚ฐํ•˜๊ณ , ์†Œ๋น„ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ

ํ•œ์ •๋œ ๋ฒ„ํผ ๋ฌธ์ œ(bounded-buffer problem)

  • ์ด ๋ฌธ์ œ๋Š” ๊ฒฐ๊ตญ ์ค‘๊ฐ„์— ์žˆ๋Š” ๋ฒ„ํผ์˜ ํฌ๊ธฐ๊ฐ€ ํ•œ์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒ

  • ํ•œ์ •๋œ ๋ฒ„ํผ ๋ฌธ์ œ๋ผ๊ณ ๋„ ๋ถˆ๋ฆผ

Object wait(), notify()

Object.wait()

  • ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€์ง„ ๋ฝ์„ ๋ฐ˜๋‚ฉํ•˜๊ณ  ๋Œ€๊ธฐ(WAITING) ์ƒํƒœ๋กœ ์ „ํ™˜

  • ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ synchronized ๋ธ”๋ก์ด๋‚˜ ๋ฉ”์„œ๋“œ์—์„œ ๋ฝ์„ ์†Œ์œ ํ•˜๊ณ  ์žˆ์„ ๋•Œ๋งŒ ํ˜ธ์ถœ ๊ฐ€๋Šฅ

  • ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜๋œ ์Šค๋ ˆ๋“œ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ notify() or notifyAll()์„ ํ˜ธ์ถœํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์ƒํƒœ๋ฅผ ์œ ์ง€

Object.notify()

  • ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๊นจ์›€

    • ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๊ฒฝ์šฐ ๊ทธ ์ค‘ ํ•˜๋‚˜๋งŒ ๊นจ์›€

  • synchronized ๋ธ”๋ก์ด๋‚˜ ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•จ

  • ๊นจ์šด ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์„ ๋‹ค์‹œ ํš๋“ํ•  ๊ธฐํšŒ๋ฅผ ์–ป์Œ

Object.notifyAll()

  • ๋Œ€๊ธฐ ์ค‘์ธ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์›€

  • synchronized ๋ธ”๋ก์ด๋‚˜ ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•จ

  • ๋ชจ๋“  ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์–ป์Œ

  • ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์›Œ์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉ

.

Object wait(), notify()์˜ ํ•œ๊ณ„

  • ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ์ง‘ํ•ฉ ํ•˜๋‚˜์— ์ƒ์‚ฐ์ž, ์†Œ๋น„์ž ์Šค๋ ˆ๋“œ๋ฅผ ๋ชจ๋‘ ๊ด€๋ฆฌํ•˜๊ณ , notify()๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž„์˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์„ ํƒ

    • ํ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ์ƒํ™ฉ์— ์†Œ๋น„์ž๊ฐ€ ๊ฐ™์€ ์†Œ๋น„์ž๋ฅผ ๊นจ์šฐ๊ฑฐ๋‚˜

    • ํ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€๋“ ์ฐจ์žˆ๋Š”๋ฐ ์ƒ์‚ฐ์ž๊ฐ€ ๊ฐ™์€ ์ƒ์‚ฐ์ž๋ฅผ ๊นจ์šฐ๋Š” ๋น„ํšจ์œจ ๋ฐœ์ƒ

  • ๋Œ€๊ธฐ ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ๊ณ„์† ์–ป์ง€ ๋ชปํ•ด์„œ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด ์˜ฌ ์ˆ˜ ์žˆ์Œ โ†’ ์Šค๋ ˆ๋“œ ๊ธฐ์•„(starvation) ์ƒํƒœ

    • notify() ๋Œ€์‹  notifyAll()์„ ์‚ฌ์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ ๊ธฐ์•„ ๋ฌธ์ œ๋Š” ๋ง‰์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋น„ํšจ์œจ์€ ๋ง‰์ง€ ๋ชปํ•จ

.

Example

  • ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ ๋ฐœ์ƒ

    • ์Šค๋ ˆ๋“œ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•œ์ •๋œ ๋ฒ„ํผ ์ƒํ™ฉ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ

      • ๋ฒ„ํผ๊ฐ€ ๊ฐ€๋“ ์ฐฌ ๊ฒฝ์šฐ: ์ƒ์‚ฐ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„๋ฆฐ๋‹ค.

      • ๋ฒ„ํผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ: ์†Œ๋น„์ž๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์—†๋‹ค.(null)

  • ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ DeadLock

    • ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ€๊ธฐํ•˜๋Š” ๋ฐฉ๋ฒ•

    • ์ž„๊ณ„ ์˜์—ญ ์•ˆ์—์„œ ๋ฝ์„ ๋“ค๊ณ  ๋Œ€๊ธฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž„๊ณ„ ์˜์—ญ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ

    • ๋‚˜๋จธ์ง€ ์Šค๋ ˆ๋“œ๋Š” ๋ชจ๋‘ BLOCKED ์ƒํƒœ๊ฐ€ ๋˜๊ณ , ์Šค๋ ˆ๋“œ๋“ค์ด ๋ฉˆ์ถ”๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ

  • ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ Object wait(), notify() ์ ์šฉ

    • wait(), notify(), notifyAll()์„ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์ œ ํ•ด๊ฒฐ

    • ํ•˜์ง€๋งŒ, ์›ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์„ ํƒํ•ด์„œ ๊นจ์šธ ์ˆ˜ ์—†์–ด ๋น„ํšจ์œจ ๋ฐœ์ƒ


Lock Condition

Example

Object.notify() vs Condition.signal()

Object.notify()

  • ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ์ž„์˜์˜ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์„œ ๊นจ์›€

    • ์Šค๋ ˆ๋“œ๊ฐ€ ๊นจ์–ด๋‚˜๋Š” ์ˆœ์„œ๋Š” ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๊ณ , JVM ๊ตฌํ˜„์— ๋”ฐ๋ผ ์ฐจ์ด

    • ๋ณดํ†ต์€ ๋จผ์ € ๋“ค์–ด์˜จ ์Šค๋ ˆ๋“œ๊ฐ€ ๋จผ์ € ์ˆ˜ํ–‰๋˜์ง€๋งŒ ๊ตฌํ˜„์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ

  • synchronized ๋ธ”๋ก ๋‚ด์—์„œ ๋ชจ๋‹ˆํ„ฐ ๋ฝ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ํ˜ธ์ถœํ•ด์•ผ ํ•จ

Condition.signal()

  • ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๊นจ์›€

    • ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” FIFO ์ˆœ์„œ๋กœ ๊นจ์šฐ๊ณ , ์ž๋ฐ” ๋ฒ„์ „๊ณผ ๊ตฌํ˜„์— ๋”ฐ๋ผ ์ฐจ์ด

    • ๋ณดํ†ต Condition ๊ตฌํ˜„์€ Queue ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— FIFO ์ˆœ์„œ

  • ReentrantLock ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ํ˜ธ์ถœํ•ด์•ผ ํ•จ


์Šค๋ž˜๋“œ์˜ ๋Œ€๊ธฐ

synchronized ๋Œ€๊ธฐ

  • ๋Œ€๊ธฐ1: ๋ชจ๋‹ˆํ„ฐ ๋ฝ ํš๋“ ๋Œ€๊ธฐ

    • ์ž๋ฐ” ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๋ฝ ๋Œ€๊ธฐ ์ง‘ํ•ฉ(๋ชจ๋‹ˆํ„ฐ ๋ฝ ๋Œ€๊ธฐ ์ง‘ํ•ฉ)์—์„œ ๊ด€๋ฆฌ

    • BLOCKED ์ƒํƒœ๋กœ ๋ฝ ํš๋“ ๋Œ€๊ธฐ

    • synchronized ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ๋ฝ์ด ์—†์œผ๋ฉด ๋Œ€๊ธฐ

    • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ synchronized ๋ฅผ ๋น ์ ธ๋‚˜๊ฐˆ ๋•Œ ๋ฝ์„ ํš๋“ ์‹œ๋„

      • ๋ฝ์„ ํš๋“ํ•˜๋ฉด ๋ฝ ๋Œ€๊ธฐ ์ง‘ํ•ฉ ํƒˆ์ถœ

  • ๋Œ€๊ธฐ2: wait() ๋Œ€๊ธฐ

    • wait() ํ˜ธ์ถœ ์‹œ ์ž๋ฐ” ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ์ง‘ํ•ฉ์—์„œ ๊ด€๋ฆฌ

    • WAITING ์ƒํƒœ๋กœ ๋Œ€๊ธฐ

    • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ notify() ํ˜ธ์ถœ ์‹œ ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ์ง‘ํ•ฉ ํƒˆ์ถœ

์ž๋ฐ”(synchronized)์˜ ๋ชจ๋“  ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์™€ ์ž„๊ณ„ ์˜์—ญ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์— 3๊ฐ€์ง€ ๊ธฐ๋ณธ ์š”์†Œ๋ฅผ ๊ฐ€์ง

  • ๋ชจ๋‹ˆํ„ฐ ๋ฝ

  • ๋ฝ ๋Œ€๊ธฐ ์ง‘ํ•ฉ(๋ชจ๋‹ˆํ„ฐ ๋ฝ ๋Œ€๊ธฐ ์ง‘ํ•ฉ) / 1์ฐจ ๋Œ€๊ธฐ์†Œ

  • ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ์ง‘ํ•ฉ / 2์ฐจ ๋Œ€๊ธฐ์†Œ

...

ReentrantLock ๋Œ€๊ธฐ

  • ๋Œ€๊ธฐ1: ReentrantLock ๋ฝ ํš๋“ ๋Œ€๊ธฐ

    • ReentrantLock ์˜ ๋Œ€๊ธฐ ํ์—์„œ ๊ด€๋ฆฌ

    • WAITING ์ƒํƒœ๋กœ ๋ฝ ํš๋“ ๋Œ€๊ธฐ

    • lock.lock() ํ˜ธ์ถœ ์‹œ ๋ฝ์ด ์—†์œผ๋ฉด ๋Œ€๊ธฐ

    • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ lock.unlock() ํ˜ธ์ถœ ์‹œ ๋Œ€๊ธฐ๊ฐ€ ํ’€๋ฆฌ๋ฉฐ ๋ฝ ํš๋“ ์‹œ๋„

      • ๋ฝ์„ ํš๋“ํ•˜๋ฉด ๋Œ€๊ธฐ ํ ํƒˆ์ถœ

  • ๋Œ€๊ธฐ2: await() ๋Œ€๊ธฐ

    • condition.await() ํ˜ธ์ถœ ์‹œ condition ๊ฐ์ฒด์˜ ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ๊ณต๊ฐ„์—์„œ ๊ด€๋ฆฌ

    • WAITING ์ƒ๋Œ€๋กœ ๋Œ€๊ธฐ

    • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ condition.signal() ํ˜ธ์ถœ ์‹œ condition ๊ฐ์ฒด์˜ ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ๊ณต๊ฐ„์—์„œ ํƒˆ์ถœ

BlockingQueue

์ž๋ฐ”๋Š” ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด

java.util.concurrent.BlockingQueue ๋ผ๋Š” ํŠน๋ณ„ํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณต

ํ๊ฐ€ ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋  ๋•Œ๊นŒ์ง€ ์Šค๋ ˆ๋“œ์˜ ์ž‘์—…์„ ์ฐจ๋‹จ(blocking)

  • ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ ์ฐจ๋‹จ

    • ํ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ ์ž‘์—…(put())์„ ์‹œ๋„ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ๊ณต๊ฐ„์ด ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ์ฐจ๋‹จ

  • ๋ฐ์ดํ„ฐ ํš๋“ ์ฐจ๋‹จ

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ํš๋“ ์ž‘์—…(take())์„ ์‹œ๋„ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ํ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ์ฐจ๋‹จ

BlockingQueue ์ธํ„ฐ์ด์Šค ์ฃผ์š” ๋ฉ”์„œ๋“œ

public interface BlockingQueue<E> extends Queue<E> {
  // ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
  boolean add(E e);
  boolean offer(E e);
  void put(E e) throws InterruptedException;
  boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
  // ๋ฐ์ดํ„ฐ ํš๋“
  E take() throws InterruptedException;
  E poll(long timeout, TimeUnit unit) throws InterruptedException;
  boolean remove(Object o);
  //...
}

๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด

  • ArrayBlockingQueue

  • LinkedBlockingQueue

  • BlockingDeque

BlockingQueue example

...

BlockingQueue ๊ธฐ๋Šฅ

ํ๊ฐ€ ๊ฐ€๋“ ์ฐผ์„ ๋•Œ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ์„ ํƒ์ง€

  • ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ณ , ์˜ˆ์™ธ๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ

  • ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ , ์ฆ‰์‹œ false ๋ฐ˜ํ™˜

  • ๋Œ€๊ธฐ

  • ํŠน์ • ์‹œ๊ฐ„ ๋งŒํผ๋งŒ ๋Œ€๊ธฐ

Throws exception
Special value
Blocks
Times out

Insert

add(e)

offer(e)

put(e)

offer(e, time, unit)

Remove

remove()

poll()

take()

poll(time, unit)

Examine

element()

peek()

not applicable

not applicable

Throws Exception / ๋Œ€๊ธฐ ์‹œ ์˜ˆ์™ธ

  • add(e): ์ง€์ •๋œ ์š”์†Œ๋ฅผ ํ์— ์ถ”๊ฐ€

    • ํ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด IllegalStateException ์˜ˆ์™ธ

  • remove(): ํ์—์„œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉฐ ๋ฐ˜ํ™˜

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด NoSuchElementException ์˜ˆ์™ธ

  • element(): ํ์˜ ๋จธ๋ฆฌ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์š”์†Œ๋ฅผ ํ์—์„œ ์ œ๊ฑฐํ•˜์ง€ ์•Š์Œ

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด NoSuchElementException ์˜ˆ์™ธ

Special Value / ๋Œ€๊ธฐ ์‹œ ์ฆ‰์‹œ ๋ฐ˜ํ™˜

  • offer(e): ์ง€์ •๋œ ์š”์†Œ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„

    • ํ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด false ๋ฐ˜ํ™˜

  • poll(): ํ์—์„œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด null ๋ฐ˜ํ™˜

  • peek(): ํ์˜ ๋จธ๋ฆฌ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์š”์†Œ๋ฅผ ํ์—์„œ ์ œ๊ฑฐํ•˜์ง€ ์•Š์Œ

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด null ๋ฐ˜ํ™˜

Blocks / ๋Œ€๊ธฐ

  • put(e): ์ง€์ •๋œ ์š”์†Œ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

    • ํ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด ๊ณต๊ฐ„์ด ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

  • take(): ํ์—์„œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜

    • ํ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ์š”์†Œ๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

  • Examine (๊ด€์ฐฐ): ํ•ด๋‹น ์‚ฌํ•ญ ์—†์Œ.

Times Out / ์‹œ๊ฐ„ ๋Œ€๊ธฐ

  • offer(e, time, unit): ์ง€์ •๋œ ์š”์†Œ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„

    • ์ง€์ •๋œ ์‹œ๊ฐ„ ๋™์•ˆ ํ๊ฐ€ ๋น„์›Œ์ง€๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋‹ค๊ฐ€ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜๋ฉด false ๋ฐ˜ํ™˜

  • poll(time, unit): ํ์—์„œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜

    • ํ์— ์š”์†Œ๊ฐ€ ์—†๋‹ค๋ฉด ์ง€์ •๋œ ์‹œ๊ฐ„ ๋™์•ˆ ์š”์†Œ๊ฐ€ ์ค€๋น„๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋‹ค๊ฐ€ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜๋ฉด null ๋ฐ˜ํ™˜

  • Examine (๊ด€์ฐฐ): ํ•ด๋‹น ์‚ฌํ•ญ ์—†์Œ

.

๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ


CAS / ์›์ž์  ์—ฐ์‚ฐ

์›์ž์  ์—ฐ์‚ฐ(atomic operation)

  • ํ•ด๋‹น ์—ฐ์‚ฐ์ด ๋” ์ด์ƒ ๋‚˜๋ˆŒ ์ˆ˜ ์—†๋Š” ๋‹จ์œ„๋กœ ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ

  • ์ค‘๋‹จ๋˜์ง€ ์•Š๊ณ , ๋‹ค๋ฅธ ์—ฐ์‚ฐ๊ณผ ๊ฐ„์„ญ ์—†์ด ์™„์ „ํžˆ ์‹คํ–‰๋˜๊ฑฐ๋‚˜ ์ „ํ˜€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์„ฑ์งˆ

  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ƒํ™ฉ์—์„œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ๊ฐ„์„ญ ์—†์ด ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š” ์—ฐ์‚ฐ

volatile int i = 0;
i = 1; // ์›์ž์  ์—ฐ์‚ฐ O
i = i + 1; // ์›์ž์ น ์—ฐ์‚ฐ X

commit

...

CAS ์—ฐ์‚ฐ

์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ CAS ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ๊ณ ๋งŒ

AtomicInteger์™€ ๊ฐ™์€ CAS ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ž˜ ์‚ฌ์šฉํ•˜๋Š” ์ •๋„๋ฉด ์ถฉ๋ถ„

CAS(CompareAnd-Swap, Compare-And-Set) ์—ฐ์‚ฐ

  • ๋ฝ์„ ๊ฑธ์ง€ ์•Š๊ณ  ์›์ž์ ์ธ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰

    • ๋ฝ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— lock-free ๊ธฐ๋ฒ•

  • ๋ฝ์„ ์™„์ „ํžˆ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ , ์ž‘์€ ๋‹จ์œ„์˜ ์ผ๋ถ€ ์˜์—ญ์— ์ ์šฉ ๊ฐ€๋Šฅ

    • ๊ธฐ๋ณธ์€ ๋ฝ์„ ์‚ฌ์šฉํ•˜๊ณ , ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ์— CAS๋ฅผ ์ ์šฉ

AtomicInteger atomicInteger = new AtomicInteger();
// atomicInteger ๊ฐ’์ด 0์ผ ๊ฒฝ์šฐ 1๋กœ ๋ณ€๊ฒฝ(์›์ž์ ์œผ๋กœ ์‹คํ–‰)
boolean result1 = atomicInteger.compareAndSet(0, 1);

incrementAndGet ๊ตฌํ˜„

.

CPU ํ•˜๋“œ์›จ์–ด์˜ ์ง€์›

  • CAS ์—ฐ์‚ฐ์€ ์›์ž์ ์ด์ง€ ์•Š์€ ๋‘ ๊ฐœ์˜ ์—ฐ์‚ฐ์„ CPU ํ•˜๋“œ์›จ์–ด ์ฐจ์›์—์„œ ํ•˜๋‚˜์˜ ์›์ž์ ์ธ ์—ฐ์‚ฐ์œผ๋กœ ๋ฌถ์–ด์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ

    • ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐœ์ž… ๋ถˆ๊ฐ€

    • CPU ์ž…์žฅ์—์„œ ๋ณด๋ฉด ์•„์ฃผ ์ฐฐ๋‚˜์˜ ์ˆœ๊ฐ„์ด๋ฏ€๋กœ ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ๋ผ์น˜์ง€๋Š” ์•Š์Œ

  • ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ํ•˜๋“œ์›จ์–ด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ

  • ๋Œ€๋ถ€๋ถ„์˜ ํ˜„๋Œ€ CPU๋“ค์€ CAS ์—ฐ์‚ฐ์„ ์œ„ํ•œ ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณต

  • CPU๋Š” ๋‘ ์—ฐ์‚ฐ์„ ๋ฌถ์–ด์„œ ํ•˜๋‚˜์˜ ์›์ž์ ์ธ ๋ช…๋ น์œผ๋กœ ๋งŒ๋“ค์–ด๋ฒ„๋ฆฐ๋‹ค. ๋”ฐ๋ผ์„œ

.

CAS(Compare-And-Swap)์™€ ๋ฝ(Lock) ๋ฐฉ์‹์˜ ๋น„๊ต

๋ฝ(Lock) ๋ฐฉ์‹

  • ๋น„๊ด€์ (pessimistic) ์ ‘๊ทผ๋ฒ•

  • ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ํ•ญ์ƒ ๋ฝ์„ ํš๋“

  • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ ‘๊ทผ์„ ๋ง‰์Œ

    • "๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐฉํ•ดํ•  ๊ฒƒ์ด๋‹ค"๋ผ๊ณ  ๊ฐ€์ •

  • ์ถฉ๋Œ ์‹œ ๋™์ž‘

    • ์Šค๋ ˆ๋“œ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด 1,000๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋‘ ๋ฝ์„ ํš๋“ํ•˜๊ณ  ๋ฐ˜ํ™˜

    • ๋ฝ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— 1,000๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋Š” ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ์ˆ˜ํ–‰

    • ์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๊ฐ€ ๊ณ„์† ์ „ํ™˜๋˜๋ฉด์„œ OS๋Š” Context switch ๋กœ ํฐ ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐœ์ƒ ๊ฐ€๋Šฅ

CAS(Compare-And-Swap) ๋ฐฉ์‹

  • ๋‚™๊ด€์ (optimistic) ์ ‘๊ทผ๋ฒ•

  • ๋ฝ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ์— ๋ฐ”๋กœ ์ ‘๊ทผ

  • ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ๊ทธ๋•Œ ์žฌ์‹œ๋„

    • "๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ถฉ๋Œ์ด ์—†์„ ๊ฒƒ์ด๋‹ค"๋ผ๊ณ  ๊ฐ€์ •

  • ์ถฉ๋Œ์ด ๋งŽ์ด ์—†๋Š” ๊ฒฝ์šฐ์— CAS ์—ฐ์‚ฐ์ด ๋น ๋ฅธ ์„ฑ๋Šฅ

  • ์ถฉ๋Œ ์‹œ ๋™์ž‘

    • 1000๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋ชจ๋‘ ํ•œ ๋ฒˆ์— ์‹คํ–‰

    • ์ถฉ๋Œ์ด ๋‚˜๋Š” 50๊ฐœ์˜ ๊ฒฝ์šฐ๋งŒ ์žฌ์‹œ๋„

    • ์ถฉ๋Œ์ด ์ ์€ ๊ฐ„๋‹จํ•œ CPU ์—ฐ์‚ฐ์—๋Š” ์ข‹์€ ์„ฑ๋Šฅ

...

CAS ๋ฝ

CAS๋Š” ๋‹จ์ˆœํ•œ ์—ฐ์‚ฐ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

commit

while(
    if (!lock) { //1. ๋ฝ ์‚ฌ์šฉ ์—ฌ๋ถ€ ํ™•์ธ
        lock = true; //2. ๋ฝ์˜ ๊ฐ’ ๋ณ€๊ฒฝ
    }
)

...

while(lock.compareAndSet(false, true)) {}

๋™๊ธฐํ™” ๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ํ•˜์ง€ ๋ชปํ•˜๋ฉด BLOCKED, WAITING ๋“ฑ์œผ๋กœ ์ƒํƒœ๊ฐ€ ์ „ํ™˜

  • ๋Œ€๊ธฐ ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์›Œ์•ผ ํ•˜๋Š” ๋ฌด๊ฒ๊ณ  ๋ณต์žกํ•œ ๊ณผ์ •์ด ์ถ”๊ฐ€๋กœ ๋™์ž‘

  • ๋”ฐ๋ผ์„œ ์„ฑ๋Šฅ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆด ์ˆ˜ ์žˆ์Œ

๋ฐ˜๋ฉด, CAS๋ฅผ ํ™œ์šฉํ•œ ๋ฝ ๋ฐฉ์‹์€ ๋ฝ์ด ์—†๋Š” ๋ฐฉ์‹

  • ๋‹จ์ˆœํžˆ while๋ฌธ์„ ๋ฐ˜๋ณต

  • ๋”ฐ๋ผ์„œ ๋Œ€๊ธฐํ•˜๋Š” ์Šค๋ ˆ๋“œ๋„ RUNNABLE ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๊ฒŒ ์ž‘๋™

...

โ„น๏ธ ์Šคํ•€ ๋ฝ

  • ๋ฝ์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด ์ž์›์„ ์†Œ๋ชจํ•˜๋ฉด์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ™•์ธ(์Šคํ•€)ํ•˜๋Š” ๋ฝ ๋ฉ”์ปค๋‹ˆ์ฆ˜

    • ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ ํ•  ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๋Š” ๊ฒƒ์„ ์Šคํ•€ ๋Œ€๊ธฐ(spin-wait)

    • ๋˜๋Š” CPU ์ž์›์„ ๊ณ„์† ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐ”์˜๊ฒŒ ๋Œ€๊ธฐํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”์œ ๋Œ€๊ธฐ(busy-wait)๋ผ๊ณ  ๋ถˆ๋ฆผ

    • ๋”ฐ๋ผ์„œ, ์Šคํ•€ ๋ฝ ๋ฐฉ์‹์€ ์•„์ฃผ ์งง์€ CPU ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•ด์•ผ ํšจ์œจ์ 

    • ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์˜คํžˆ๋ ค CPU ์ž์›์„ ๋” ๋งŽ์ด ์‚ฌ์šฉ

  • CAS๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„

...

๋ฝ VS CAS ์‚ฌ์šฉ ๋ฐฉ์‹

๋™๊ธฐํ™” ๋ฝ(synchronized , Lock(ReentrantLock))์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ CAS๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฝ ํ”„๋ฆฌ ๋ฐฉ์‹์˜ ์žฅ๋‹จ์  ๋น„๊ต

CAS

์žฅ์ 

  • ๋‚™๊ด€์  ๋™๊ธฐํ™”

    • ๋ฝ์„ ๊ฑธ์ง€ ์•Š๊ณ ๋„ ๊ฐ’์„ ์•ˆ์ „ํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ

    • CAS๋Š” ์ถฉ๋Œ์ด ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์—ฌ ์ถฉ๋Œ์ด ์ ์€ ํ™˜๊ฒฝ์—์„œ ๋†’์€ ์„ฑ๋Šฅ์„ ๋ฐœํœ˜

  • ๋ฝ ํ”„๋ฆฌ(Lock-Free)

    • ๋ฝ์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ฐ„์ด ์—†์Œ

    • ๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋กœํ‚น๋˜์ง€ ์•Š์œผ๋ฉฐ, ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Œ

๋‹จ์ 

  • ์ถฉ๋Œ์ด ๋นˆ๋ฒˆํ•œ ๊ฒฝ์šฐ

    • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๋™์ผํ•œ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹œ๋„ํ•  ๋•Œ ์ถฉ๋Œ ๋ฐœ์ƒ

    • ์ถฉ๋Œ ๋ฐœ์ƒ ์‹œ CAS๋Š” ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ์žฌ์‹œ๋„, ์ด์— ๋”ฐ๋ผ CPU ์ž์›์„ ๊ณ„์† ์†Œ๋ชจ

    • ๋ฐ˜๋ณต์ ์ธ ์žฌ์‹œ๋„๋กœ ์ธํ•ด ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ

  • ์Šคํ•€๋ฝ๊ณผ ์œ ์‚ฌํ•œ ์˜ค๋ฒ„ํ—ค๋“œ

    • ์ถฉ๋Œ ์‹œ ๋ฐ˜๋ณต์ ์ธ ์žฌ์‹œ๋„๋กœ ๊ณ„์† ๋ฐ˜๋ณต๋˜๋ฉด ์Šคํ•€๋ฝ๊ณผ ์œ ์‚ฌํ•œ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐœ์ƒ

    • ํŠนํžˆ ์ถฉ๋Œ ๋นˆ๋„๊ฐ€ ๋†’์„์ˆ˜๋ก ์ด๋Ÿฐ ํ˜„์ƒ์ด ๋‘๋“œ๋Ÿฌ์ง

์‚ฌ์šฉ ์‚ฌ๋ก€

  • CPU ์‚ฌ์ดํด์ด ๊ธˆ๋ฐฉ ๋๋‚˜์ง€๋งŒ ์•ˆ์ „ํ•œ ์ž„๊ณ„ ์˜์—ญ/์›์ž์ ์ธ ์—ฐ์‚ฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ

    • ์ˆซ์ž ๊ฐ’์˜ ์ฆ๊ฐ€

    • ์ž๋ฃŒ ๊ตฌ์กฐ์˜ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€/์‚ญ์ œ

.

๋™๊ธฐํ™” ๋ฝ

์žฅ์ 

  • ์ถฉ๋Œ ๊ด€๋ฆฌ

    • ๋ฝ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜์—ฌ ์ถฉ๋Œ ๋ฐฉ์ง€

    • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฒฝ์Ÿํ•  ๊ฒฝ์šฐ์—๋„ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘

  • ์•ˆ์ •์„ฑ

    • ๋ณต์žกํ•œ ์ƒํ™ฉ์—์„œ๋„ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋™์ž‘์„ ๋ณด์žฅ

  • ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ

    • ๋ฝ์„ ๋Œ€๊ธฐํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” CPU๋ฅผ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ

๋‹จ์ 

  • ๋ฝ ํš๋“ ๋Œ€๊ธฐ ์‹œ๊ฐ„

    • ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฝ์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐํ•˜์—ฌ, ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์Œ

  • ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ์˜ค๋ฒ„ํ—ค๋“œ

    • ๋ฝ ํš๋“์„ ๋Œ€๊ธฐํ•˜๋Š” ์‹œ์ ๊ณผ ๋˜ ๋ฝ์„ ํš๋“ํ•˜๋Š” ์‹œ์ ์— ์Šค๋ ˆ๋“œ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ

    • ์ด๋•Œ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋กœ ์ธํ•ด ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ฆ๊ฐ€

์‚ฌ์šฉ ์‚ฌ๋ก€

  • ์˜ค๋ž˜ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ž‘์—…

    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋Œ€๊ธฐ

    • ๋‹ค๋ฅธ ์„œ๋ฒ„์˜ ์š”์ฒญ ๋Œ€๊ธฐ

์ง์ ‘ CAS ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†๊ณ , ๋Œ€๋ถ€๋ถ„ ๋ณต์žกํ•œ ๋™์‹œ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด CAS ์—ฐ์‚ฐ์„ ์‚ฌ์šฉ

AtomicInteger์™€ ๊ฐ™์€ CAS ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ž˜ ์‚ฌ์šฉํ•˜๋Š” ์ •๋„๋ฉด ์ถฉ๋ถ„


๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜

์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์—ฐ์‚ฐ์€ ์›์ž์ ์ธ ์—ฐ์‚ฐ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์Šค๋ ˆ๋“œ ์„ธ์ดํ”„ ํ•˜์ง€ ์•Š๋‹ค.

commit

ํ”„๋ก์‹œ ํŒจํ„ด์˜ ์ฃผ์š” ๋ชฉ์ 

  • ์ ‘๊ทผ ์ œ์–ด: ์‹ค์ œ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๊ฑฐ๋‚˜ ํ†ต์ œ

  • ์„ฑ๋Šฅ ํ–ฅ์ƒ: ์‹ค์ œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์„ ์ง€์—ฐ์‹œํ‚ค๊ฑฐ๋‚˜ ์บ์‹ฑํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”

  • ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ ์ œ๊ณต: ์‹ค์ œ ๊ฐ์ฒด์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ(๋กœ๊น…, ์ธ์ฆ, ๋™๊ธฐํ™” ๋“ฑ)์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ œ๊ณต

.

์ž๋ฐ” synchronized ํ”„๋ก์‹œ

  • Collections๋Š” ๋‹ค์–‘ํ•œ synchronized ๋™๊ธฐํ™” ๋ฉ”์„œ๋“œ ์ง€์›

  • List, Collection, Map, Set ๋“ฑ ๋‹ค์–‘ํ•œ ๋™๊ธฐํ™” ํ”„๋ก์‹œ ์ƒ์„ฑ ๊ฐ€๋Šฅ

    • synchronizedList()

    • synchronizedCollection()

    • synchronizedMap()

    • synchronizedSet()

    • synchronizedNavigableMap()

    • synchronizedNavigableSet()

    • synchronizedSortedMap()

    • synchronizedSortedSet()

synchronized ํ”„๋ก์‹œ ๋ฐฉ์‹์˜ ๋‹จ์ 

  • ๋™๊ธฐํ™” ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐœ์ƒ

  • ์ „์ฒด ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•ด ๋™๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๋ฏ€๋กœ ์ž ๊ธˆ ๋ฒ”์œ„๊ฐ€ ๋„“์–ด์ง

  • ์ •๊ตํ•œ ๋™๊ธฐํ™” ๋ถˆ๊ฐ€

.

์ž๋ฐ” ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜

  • java.util.concurrent ํŒจํ‚ค์ง€์—๋Š” ๊ณ ์„ฑ๋Šฅ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์„ ์ง€์›ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค๋“ค์„ ์ œ๊ณต

  • synchronized, Lock(ReentrantLock), CAS, ๋ถ„ํ•  ์ž  ๊ธˆ ๊ธฐ์ˆ (segment lock)๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์„ž์–ด์„œ ๋งค์šฐ ์ •๊ตํ•œ ๋™๊ธฐํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋™์‹œ์— ์„ฑ๋Šฅ๋„ ์ตœ์ ํ™”

๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜์˜ ์ข…๋ฅ˜

  • List

    • CopyOnWriteArrayList โ†’ ArrayList ๋Œ€์•ˆ

  • Set

    • CopyOnWriteArraySet โ†’ HashSet ๋Œ€์•ˆ

    • ConcurrentSkipListSet โ†’ TreeSet ๋Œ€์•ˆ(์ •๋ ฌ๋œ ์ˆœ์„œ ์œ ์ง€, Comparator ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

  • Map

    • ConcurrentHashMap โ†’ HashMap ๋Œ€์•ˆ

    • ConcurrentSkipListMap โ†’ TreeMap ๋Œ€์•ˆ(์ •๋ ฌ๋œ ์ˆœ์„œ ์œ ์ง€, Comparator ์‚ฌ์šฉ ๊ฐ€๋Šฅ)

  • Queue

    • ConcurrentLinkedQueue: ๋™์‹œ์„ฑ ํ, ๋น„ ์ฐจ๋‹จ(non-blocking) ํ

  • Deque

    • ConcurrentLinkedDeque: ๋™์‹œ์„ฑ ๋ฐํฌ, ๋น„ ์ฐจ๋‹จ(non-blocking) ํ

LinkedHashSet, LinkedHashMap ์ฒ˜๋Ÿผ ์ž…๋ ฅ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌํ˜„์ฒด๋Š” ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ , ํ•„์š”ํ•˜๋‹ค๋ฉด Collections.synchronizedXxx() ์‚ฌ์šฉ

์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜๋Š” ๋ธ”๋กœํ‚น ํ(BlockingQueue)

  • ArrayBlockingQueue

    • ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋œ ๋ธ”๋กœํ‚น ํ

    • ๊ณต์ •(fair) ๋ชจ๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ๋‹จ, ๊ณต์ • ๋ชจ๋“œ ์‚ฌ์šฉ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜ ๊ฐ€๋Šฅ์„ฑ

  • LinkedBlockingQueue

    • ํฌ๊ธฐ๊ฐ€ ๋ฌดํ•œํ•˜๊ฑฐ๋‚˜ ๊ณ ์ •๋œ ๋ธ”๋กœํ‚น ํ

  • PriorityBlockingQueue

    • ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์š”์†Œ๋ฅผ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๋Š” ๋ธ”๋กœํ‚น ํ

  • SynchronousQueue

    • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๋ธ”๋กœํ‚น ํ

    • ์ƒ์‚ฐ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์†Œ๋น„์ž๊ฐ€ ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

    • ์ƒ์‚ฐ์ž-์†Œ๋น„์ž ๊ฐ„์˜ ์ง์ ‘์ ์ธ ํ•ธ๋“œ์˜คํ”„(hand-off) ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ œ๊ณต

      • ์ค‘๊ฐ„์— ํ ์—†์ด ์ƒ์‚ฐ์ž, ์†Œ๋น„์ž๊ฐ€ ์ง์ ‘ ๊ฑฐ๋ž˜

  • DelayQueue

    • ์ง€์—ฐ๋œ ์š”์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ธ”๋กœํ‚น ํ

    • ๊ฐ ์š”์†Œ๋Š” ์ง€์ •๋œ ์ง€์—ฐ ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์—์•ผ ์†Œ๋น„

    • ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์Šค์ผ€์ค„๋ง ์ž‘์—…์— ์‚ฌ์šฉ

Thread Pool And Executor

โ„น๏ธ ์Šค๋ ˆ๋“œ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์˜ ๋ฌธ์ œ์ 

1). ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ์‹œ๊ฐ„์œผ๋กœ ์ธํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ

  • ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น:

    • ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ์ž์‹ ๋งŒ์˜ ํ˜ธ์ถœ ์Šคํƒ(call stack)์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•จ

      • ์ด ํ˜ธ์ถœ ์Šคํƒ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„

    • ๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ์ด ํ˜ธ์ถœ ์Šคํƒ์„ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น

  • ์šด์˜์ฒด์ œ ์ž์› ์‚ฌ์šฉ:

    • ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์€ ์šด์˜์ฒด์ œ ์ปค๋„ ์ˆ˜์ค€์—์„œ ์ด๋ฃจ์–ด์ง€๋ฉฐ

    • ์‹œ์Šคํ…œ ์ฝœ(system call)์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ

    • ์ด๋Š” CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋ชจํ•˜๋Š” ์ž‘์—…

  • ์šด์˜์ฒด์ œ ์Šค์ผ€์ค„๋Ÿฌ ์„ค์ •:

    • ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ์šด์˜์ฒด์ œ์˜ ์Šค์ผ€์ค„๋Ÿฌ๋Š” ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์กฐ์ •ํ•ด์•ผ ํ•จ

    • ์ด๋Š” ์šด์˜์ฒด์ œ์˜ ์Šค์ผ€์ค„๋ง ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋”ฐ๋ผ ์ถ”๊ฐ€์ ์ธ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์ž‡์Œ

      • ์ฐธ๊ณ ๋กœ ์Šค๋ ˆ๋“œ ํ•˜๋‚˜๋Š” ๋ณดํ†ต 1MB ์ด์ƒ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉ

2). ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ ๋ฌธ์ œ

  • ์„œ๋ฒ„์˜ CPU, ๋ฉ”๋ชจ๋ฆฌ ์ž์›์€ ํ•œ์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์Šค๋ ˆ๋“œ๋Š” ๋ฌดํ•œํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์—†์Œ

  • ์‹œ์Šคํ…œ์ด ๋ฒ„ํ‹ธ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์Šค๋ ˆ๋“œ์˜ ์ˆ˜ ๊นŒ์ง€๋งŒ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ด€๋ฆฌ ํ•„์š”

  • ์ธํ„ฐ๋ŸฝํŠธ ๋“ฑ์˜ ์‹ ํ˜ธ๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”

3). Runnable ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ถˆํŽธํ•จ

  • ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†์Œ:

    • ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ณ„๋„์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ํ•„์š”

    • ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ๋„ฃ์–ด๋‘๊ณ , join() ๋“ฑ์„ ์‚ฌ์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ๋ณด๊ด€ํ•œ ๊ฐ’์„ ๋ฐ›์•„์•ผ ํ•จ

  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ:

    • ์ฒดํฌ ์˜ˆ์™ธ(checked exception)๋ฅผ ๋˜์งˆ ์ˆ˜ ์—†์Œ

    • ์ฒดํฌ ์˜ˆ์™ธ์˜ ์ฒ˜๋ฆฌ๋Š” ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ์ฒ˜๋ฆฌ ํ•„์š”

Executor Framework

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋ฐ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๊ธฐ๋Šฅ์˜ ๋ชจ์Œ

์ž‘์—… ์‹คํ–‰ ๊ด€๋ฆฌ, ์Šค๋ ˆ๋“œ ํ’€ ๊ด€๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ณต์žกํ•จ ํ•ด์†Œ

์Šค๋ ˆ๋“œ ํ’€, ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ, Runnable์˜ ๋ฌธ์ œ์ , ์ƒ์‚ฐ์ž ์†Œ๋น„์ž ๋ฌธ์ œ๊นŒ์ง€ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ์ž๋ฐ” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ตœ๊ณ ์˜ ๋„๊ตฌ

package java.util.concurrent;

public interface Executor {
    void execute(Runnable command);
}

Executor

/** ExecutorService
 * Executor Framework ์‚ฌ์šฉ ์‹œ ๋Œ€๋ถ€๋ถ„ ExecutorService ์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์šฉ
 * ExecutorService ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด๋Š” ThreadPoolExecutor
 */
public interface ExecutorService extends Executor, AutoCloseable {
    <T> Future<T> submit(Callable<T> task);
    
    @Override
    default void close(){...}

    ...
}

ExecutorService

Runnable๊ณผ Callable ๋น„๊ต

.

ExecutorService ์ค‘๋ฃŒ ๋ฉ”์„œ๋“œ

  • ์„œ๋น„์Šค ์ข…๋ฃŒ

    • void shutdown()

      • ์ƒˆ๋กœ์šด ์ž‘์—…์„ ๋ฐ›์ง€ ์•Š๊ณ , ์ด๋ฏธ ์ œ์ถœ๋œ ์ž‘์—…์„ ๋ชจ๋‘ ์™„๋ฃŒํ•œ ํ›„์— ์ข…๋ฃŒ

      • ๋…ผ ๋ธ”๋กœํ‚น ๋ฉ”์„œ๋“œ

    • List<Runnable> shutdownNow()

      • ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ณ , ๋Œ€๊ธฐ ์ค‘์ธ ์ž‘์—…์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ ์ฆ‰์‹œ ์ข…๋ฃŒ

      • ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ธฐ ์œ„ํ•ด ์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ

      • ๋…ผ ๋ธ”๋กœํ‚น ๋ฉ”์„œ๋“œ

  • ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ

    • boolean isShutdown()

      • ์„œ๋น„์Šค๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

    • boolean isTerminated()

      • shutdown(), shutdownNow() ํ˜ธ์ถœ ํ›„, ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

  • ์ž‘์—… ์™„๋ฃŒ ๋Œ€๊ธฐ

    • boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException

      • ์„œ๋น„์Šค ์ข…๋ฃŒ ์‹œ ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

      • ์ด๋•Œ ์ง€์ •๋œ ์‹œ๊ฐ„๊นŒ์ง€๋งŒ ๋Œ€๊ธฐ

      • ๋ธ”๋กœํ‚น ๋ฉ”์„œ๋“œ

    • close()

      • ์ž๋ฐ” 19๋ถ€ํ„ฐ ์ง€์›ํ•˜๋Š” ์„œ๋น„์Šค ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ

      • shutdown() ๊ณผ ๋™์ผ

      • ์ •ํ™•ํžˆ shutdown() ํ˜ธ์ถœ ํ›„, ํ•˜๋ฃจ๋ฅผ ๊ธฐ๋‹ค๋ ค๋„ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด shutdownNow() ํ˜ธ์ถœ

      • ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ์— ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ shutdownNow() ํ˜ธ์ถœ

example

Future

์ž‘์—…์˜ ๋ฏธ๋ž˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด

Future Interface

package java.util.concurrent;

public interface Future<V> {
  /** ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ž‘์—…์„ ์ทจ์†Œ
   * ์ž‘์—…์ด ์‹คํ–‰ ์ค‘์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ ์•„์ง ์‹œ์ž‘๋˜์ง€ ์•Š์•˜์œผ๋ฉด ์ทจ์†Œ 
   * ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์˜ ๊ฒฝ์šฐ mayInterruptIfRunning=true ๋ฉด ์ค‘๋‹จ ์‹œ๋„
   * - ์ทจ์†Œ ์ƒํƒœ์˜ Future ์— Future.get() ์„ ํ˜ธ์ถœํ•˜๋ฉด CancellationException ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ ๋ฐœ์ƒ
   * 
   * [๋งค๊ฐœ๋ณ€์ˆ˜]
   * mayInterruptIfRunning = true
   * - Future ๋ฅผ ์ทจ์†Œ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ
   * - ์ด๋•Œ ์ž‘์—…์ด ์‹คํ–‰์ค‘์ด๋ผ๋ฉด Thread.interrupt()๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ž‘์—… ์ค‘๋‹จ 
   *
   * mayInterruptIfRunning = false
   * - Future ๋ฅผ ์ทจ์†Œ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ
   * - ๋‹จ, ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์„ ์ค‘๋‹จํ•˜์ง€๋Š” ์•Š์Œ
   * 
   * [๋ฐ˜ํ™˜๊ฐ’]
   * - ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ทจ์†Œ๋œ ๊ฒฝ์šฐ true
   * - ์ด๋ฏธ ์™„๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์ทจ์†Œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ false
   */
  boolean cancel(boolean mayInterruptIfRunning);
  /** ์ž‘์—…์ด ์ทจ์†Œ ์—ฌ๋ถ€ ํ™•์ธ
   * ์ž‘์—…์ด cancel() ๋ฉ”์„œ๋“œ์— ์˜ํ•ด ์ทจ์†Œ๋œ ๊ฒฝ์šฐ์— true ๋ฐ˜ํ™˜
   * - ์ž‘์—…์ด ์ทจ์†Œ๋œ ๊ฒฝ์šฐ true, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ false
   */
  boolean isCancelled();

  /**  ์ž‘์—… ์™„๋ฃŒ ์—ฌ๋ถ€ ํ™•์ธ
   * ์ž‘์—…์ด ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜, ์ทจ์†Œ๋˜์—ˆ๊ฑฐ๋‚˜, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ true ๋ฐ˜ํ™˜
   * - ์ž‘์—…์ด ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ true, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ false
   */
  boolean isDone();
  
  /** ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ณ , ์™„๋ฃŒ๋˜๋ฉด ์ž‘์—… ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
   * ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ get()์„ ํ˜ธ์ถœํ•œ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ€๊ธฐ(๋ธ”๋กํ‚น)
   * ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜
   * 
   * [์˜ˆ์™ธ]
   * - InterruptedException: ๋Œ€๊ธฐ ์ค‘์— ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
   * - ExecutionException : ์ž‘์—… ๊ณ„์‚ฐ ์ค‘์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
   */
  V get() throws InterruptedException, ExecutionException;
  /** get() ๊ณผ ๊ฐ™์€๋ฐ, ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ
   * ์ง€์ •๋œ ์‹œ๊ฐ„ ๋™์•ˆ ๊ฒฐ๊ณผ๋ฅผ ๋Œ€๊ธฐ
   * ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜๋ฉด TimeoutException ๋ฐœ์ƒ
   * 
   * [๋งค๊ฐœ๋ณ€์ˆ˜]
   * - timeout : ๋Œ€๊ธฐํ•  ์ตœ๋Œ€ ์‹œ๊ฐ„
   * - unit: timeout ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์‹œ๊ฐ„ ๋‹จ์œ„ ์ง€์ •
   * 
   * [์˜ˆ์™ธ]
   * - InterruptedException : ๋Œ€๊ธฐ ์ค‘์— ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
   * - ExecutionException : ๊ณ„์‚ฐ ์ค‘์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
   * - TimeoutException : ์ฃผ์–ด์ง„ ์‹œ๊ฐ„ ๋‚ด์— ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ฐœ์ƒ
   */
  V get(long timeout, TimeUnit unit)
  throws InterruptedException, ExecutionException, TimeoutException;
  
  enum State {
      RUNNING,
      SUCCESS,
      FAILED,
      CANCELLED
  }
  
  default State state() {}
}
Future<Integer> future = es.submit(new MyCallable()); 
  • submit() ํ˜ธ์ถœ ์‹œ future ๋Š” ์ฆ‰์‹œ ๋ฐ˜ํ™˜

  • ๋•๋ถ„์— ์š”์ฒญ ์Šค๋ ˆ๋“œ๋Š” ๋ธ”๋กœํ‚น ๋˜์ง€ ์•Š๊ณ , ํ•„์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰

Integer result = future.get();
  • ์ž‘์—…์˜ ๊ฒฐ๊ณผ๊ฐ€ ํ•„์š”ํ•˜๋ฉด Future.get() ํ˜ธ์ถœ

  • Future๊ฐ€ ์™„๋ฃŒ ์ƒํƒœ:

    • Future ์— ๊ฒฐ๊ณผ๋„ ํฌํ•จ โ†’ ์š”์ฒญ ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ , ๊ฐ’์„ ์ฆ‰์‹œ ๋ฐ˜ํ™˜

  • Future๊ฐ€ ๋ฏธ์™„๋ฃŒ ์ƒํƒœ:

    • ์ž‘์—…์ด ์•„์ง ์ˆ˜ํ–‰๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์ˆ˜ํ–‰ ์ค‘ โ†’ ์š”์ฒญ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•ด ๋ธ”๋กœํ‚น ์ƒํƒœ๋กœ ๋Œ€๊ธฐ

Future ๋™์ž‘

Last updated