JavaRush /Java Blog /Random-KO /๋ณ€๋™์„ฑ ๊ด€๋ฆฌ
lexmirnov
๋ ˆ๋ฒจ 29
ะœะพัะบะฒะฐ

๋ณ€๋™์„ฑ ๊ด€๋ฆฌ

Random-KO ๊ทธ๋ฃน์— ๊ฒŒ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜ ์‚ฌ์šฉ ์ง€์นจ

๋ธŒ๋ผ์ด์–ธ ๊ฒŒ์ธ (Brian Goetz) 2007๋…„ 6์›” 19์ผ ์›๋ณธ: ๋ณ€๋™์„ฑ ๊ด€๋ฆฌ Java์˜ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋Š” "๋™๊ธฐํ™”-๋ผ์ดํŠธ"๋ผ๊ณ  ๋ถˆ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™๊ธฐํ™”๋œ ๋ธ”๋ก๋ณด๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๋” ์ ์€ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ข…์ข… ๋” ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋˜์ง€๋งŒ ๋™๊ธฐํ™”๋œ ๋ธ”๋ก์ด ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ์ผ๋ถ€๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ํœ˜๋ฐœ์„ฑ์„ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒจํ„ด๊ณผ ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•  ๊ณณ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ฒฝ๊ณ ๋ฅผ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์—๋Š” ์ƒํ˜ธ ๋ฐฐ์ œ(๋ฎคํ…์Šค)์™€ ๊ฐ€์‹œ์„ฑ์˜ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒํ˜ธ ๋ฐฐ์ œ๋Š” ์ž ๊ธˆ์ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด์„œ๋งŒ ์œ ์ง€๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ด ์†์„ฑ์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ๊ณต์œ  ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ์ œ์–ด ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์‹œ์„ฑ์€ ๋ณด๋‹ค ๋ฏธ๋ฌ˜ํ•œ ๋ฌธ์ œ์ด๋ฉฐ, ๊ทธ ๋ชฉ์ ์€ ์ž ๊ธˆ์ด ํ•ด์ œ๋˜๊ธฐ ์ „์— ๊ณต์šฉ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ•ด๋‹น ์ž ๊ธˆ์„ ์ธ๊ณ„๋ฐ›๋Š” ๋‹ค์Œ ์Šค๋ ˆ๋“œ์— ํ‘œ์‹œ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋™๊ธฐํ™”๊ฐ€ ๊ฐ€์‹œ์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์œผ๋ฉด ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์šฉ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์˜ค๋ž˜๋˜๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋กœ ์ธํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜
ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋Š” ๋™๊ธฐํ™”๋œ ๋ณ€์ˆ˜์˜ ๊ฐ€์‹œ์„ฑ ์†์„ฑ์„ ๊ฐ€์ง€์ง€๋งŒ ์›์ž์„ฑ์€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ž๋™์œผ๋กœ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜์˜ ์ตœ์‹  ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ๋งค์šฐ ์ œํ•œ๋œ ๊ฒฝ์šฐ, ์ฆ‰ ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜ ์‚ฌ์ด ๋˜๋Š” ๋ณ€์ˆ˜์˜ ํ˜„์žฌ ๊ฐ’๊ณผ ๋ฏธ๋ž˜ ๊ฐ’ ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ๋„์ž…ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค . ๋”ฐ๋ผ์„œ ํœ˜๋ฐœ์„ฑ๋งŒ์œผ๋กœ๋Š” ์นด์šดํ„ฐ, ๋ฎคํ…์Šค ๋˜๋Š” ๋ถˆ๋ณ€ ๋ถ€๋ถ„์ด ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜์™€ ์—ฐ๊ฒฐ๋œ ํด๋ž˜์Šค(์˜ˆ: "start <=end")๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœ์„ฑ ๋˜๋Š” ํ™•์žฅ์„ฑ์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์ด์œ  ์ค‘ ํ•˜๋‚˜๋กœ ํœ˜๋ฐœ์„ฑ ์ž ๊ธˆ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์–ธ์–ด ๊ตฌ์„ฑ์€ ์ž ๊ธˆ ๋Œ€์‹  ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ๊ณ  ๋‚˜์ค‘์— ์ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ž ๊ธˆ๊ณผ ๋‹ฌ๋ฆฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ํ™•์žฅ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ ์Šต๋‹ˆ๋‹ค. ์“ฐ๊ธฐ๋ณด๋‹ค ์ฝ๊ธฐ๊ฐ€ ๋” ๋งŽ์€ ์ƒํ™ฉ์—์„œ๋Š” ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๊ฐ€ ์ž ๊ธˆ์— ๋น„ํ•ด ์„ฑ๋Šฅ์ƒ์˜ ์ด์ ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํœ˜๋ฐœ์„ฑ ๋ฌผ์งˆ์˜ ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ์„ ์œ„ํ•œ ์กฐ๊ฑด
์ œํ•œ๋œ ์ƒํ™ฉ์—์„œ๋Š” ์ž ๊ธˆ์„ ํœ˜๋ฐœ์„ฑ ์ž ๊ธˆ์œผ๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ๊ธฐ์ค€์„ ๋ชจ๋‘ ์ถฉ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  1. ๋ณ€์ˆ˜์— ๊ธฐ๋ก๋˜๋Š” ๋‚ด์šฉ์€ ํ˜„์žฌ ๊ฐ’๊ณผ ๋ฌด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ณ€์ˆ˜๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜์™€์˜ ๋ถˆ๋ณ€์„ฑ์— ์ฐธ์—ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์ด๋Ÿฌํ•œ ์กฐ๊ฑด์€ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜์— ์“ธ ์ˆ˜ ์žˆ๋Š” ์œ ํšจํ•œ ๊ฐ’์ด ๋ณ€์ˆ˜์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ํฌํ•จํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ์ƒํƒœ์™€ ๋ฌด๊ด€ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์กฐ๊ฑด์€ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ ์นด์šดํ„ฐ๋กœ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. ์ฆ๋ถ„(x++)์€ ๋‹จ์ผ ์ž‘์—…์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ํœ˜๋ฐœ์„ฑ์ด ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ์›์ž์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ฝ๊ธฐ-์ˆ˜์ •-์“ฐ๊ธฐ ์ž‘์—…์˜ ์ „์ฒด ์‹œํ€€์Šค์ž…๋‹ˆ๋‹ค. ์œ ํšจํ•œ ์ž‘์—…์„ ์œ„ํ•ด์„œ๋Š” x ๊ฐ’์ด ์ž‘์—… ์ „๋ฐ˜์— ๊ฑธ์ณ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (๋‹จ, ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ๊ฐ’์„ ์“ฐ๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ๋‹ค๋ฉด ์ฒซ ๋ฒˆ์งธ ์กฐ๊ฑด์€ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ์—์„œ ์ฒซ ๋ฒˆ์งธ ๋˜๋Š” ๋‘ ๋ฒˆ์งธ ์กฐ๊ฑด์ด ์œ„๋ฐ˜๋˜๋ฏ€๋กœ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋Š” ๋™๊ธฐํ™”๋œ ๋ณ€์ˆ˜๋ณด๋‹ค ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋œ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ฉ๋‹ˆ๋‹ค. ๋ชฉ๋ก 1์€ ์ˆซ์ž ๋ฒ”์œ„๊ฐ€ ํฌํ•จ๋œ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํด๋ž˜์Šค๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ถˆ๋ณ€์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํ•˜ํ•œ์€ ํ•ญ์ƒ ์ƒํ•œ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์Šต๋‹ˆ๋‹ค. @NotThreadSafe public class NumberRange { private int lower, upper; public int getLower() { return lower; } public int getUpper() { return upper; } public void setLower(int value) { if (value > upper) throw new IllegalArgumentException(...); lower = value; } public void setUpper(int value) { if (value < lower) throw new IllegalArgumentException(...); upper = value; } } ๋ฒ”์œ„ ์ƒํƒœ ๋ณ€์ˆ˜๋Š” ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ œํ•œ๋˜๋ฏ€๋กœ ํด๋ž˜์Šค๊ฐ€ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ•˜์œ„ ๋ฐ ์ƒ์œ„ ํ•„๋“œ๋ฅผ ํœ˜๋ฐœ์„ฑ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์กฐ๋งŒ๊ฐ„ ์šด์ด ์ข‹์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ๋ถ€์ ์ ˆํ•œ ๊ฐ’์œผ๋กœ setLower() ๋ฐ setUpper()๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋กœ ์ธํ•ด ๋ฒ”์œ„๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ดˆ๊ธฐ ๊ฐ’์ด (0, 5)์ด๊ณ  ์Šค๋ ˆ๋“œ A๊ฐ€ setLower(4)๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋™์‹œ์— ์Šค๋ ˆ๋“œ B๊ฐ€ setUpper(3)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ์ธํ„ฐ๋ฆฌ๋ธŒ ์ž‘์—…์€ ๋‘˜ ๋‹ค ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•˜๋”๋ผ๋„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋ถˆ๋ณ€์„ฑ์„ ๋ณดํ˜ธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฒ”์œ„๋Š” (4, 3) - ์ž˜๋ชป๋œ ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฒ”์œ„ ์ž‘์—…์— ๋Œ€ํ•ด setLower() ๋ฐ setUpper()๋ฅผ ์›์ž์ ์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•„๋“œ๋ฅผ ํœ˜๋ฐœ์„ฑ์œผ๋กœ ๋งŒ๋“ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์„ฑ๋Šฅ ๊ณ ๋ ค ์‚ฌํ•ญ
ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ด์œ ๋Š” ๋‹จ์ˆœ์„ฑ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋Š” ๊ทธ๋Ÿฌํ•œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ด€๋ จ๋œ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ด์œ ๋Š” ์„ฑ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ํœ˜๋ฐœ์„ฑ์ด ์ž ๊ธˆ๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ Java Virtual Machine์˜ ๋‚ด๋ถ€ ์ž‘์—…๊ณผ ๊ด€๋ จํ•˜์—ฌ "X๋Š” ํ•ญ์ƒ Y๋ณด๋‹ค ๋น ๋ฆ…๋‹ˆ๋‹ค"์™€ ๊ฐ™์€ ์ •ํ™•ํ•˜๊ณ  ํฌ๊ด„์ ์ธ ์„ค๋ช…์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ๊ทนํžˆ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. (์˜ˆ๋ฅผ ๋“ค์–ด, JVM์€ ์ผ๋ถ€ ์ƒํ™ฉ์—์„œ ์ž ๊ธˆ์„ ์™„์ „ํžˆ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํœ˜๋ฐœ์„ฑ ๋Œ€ ๋™๊ธฐํ™” ๋น„์šฉ์„ ์ถ”์ƒ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๋…ผ์˜ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.) ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๋ถ€๋ถ„์˜ ์ตœ์‹  ํ”„๋กœ์„ธ์„œ ์•„ํ‚คํ…์ฒ˜์—์„œ ํœ˜๋ฐœ์„ฑ์„ ์ฝ๋Š” ๋น„์šฉ์€ ์ผ๋ฐ˜ ๋ณ€์ˆ˜๋ฅผ ์ฝ๋Š” ๋น„์šฉ๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ์„ ์ž‘์„ฑํ•˜๋Š” ๋น„์šฉ์€ ๊ฐ€์‹œ์„ฑ์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํŽœ์‹ฑ์œผ๋กœ ์ธํ•ด ์ผ๋ฐ˜ ๋ณ€์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋†’์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž ๊ธˆ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ €๋ ดํ•ฉ๋‹ˆ๋‹ค.
ํœ˜๋ฐœ์„ฑ์˜ ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ์„ ์œ„ํ•œ ํŒจํ„ด
๋งŽ์€ ๋™์‹œ์„ฑ ์ „๋ฌธ๊ฐ€๋“ค์€ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๊ฐ€ ์ž ๊ธˆ๋ณด๋‹ค ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์„ ํ”ผํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋”ฐ๋ฅด๋ฉด ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ž˜ ์ •์˜๋œ ํŒจํ„ด์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ํœ˜๋ฐœ์„ฑ์˜ ํ•œ๊ณ„๋ฅผ ์กด์ค‘ํ•˜์‹ญ์‹œ์˜ค. ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๊ณผ๋„ ๋…๋ฆฝ์ ์ธ ํœ˜๋ฐœ์„ฑ ๋ฌผ์งˆ๋งŒ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ํŒจํ„ด์œผ๋กœ ์ธํ•ด ์œ„ํ—˜ํ•œ ์˜์—ญ์— ๋น ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŒจํ„ด #1: ์ƒํƒœ ํ”Œ๋ž˜๊ทธ
์•„๋งˆ๋„ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜์˜ ์ •์‹ ์‚ฌ์šฉ์€ ์ดˆ๊ธฐํ™” ์™„๋ฃŒ ๋˜๋Š” ์ข…๋ฃŒ ์š”์ฒญ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ์ผํšŒ์„ฑ ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ„๋‹จํ•œ ๋ถ€์šธ ์ƒํƒœ ํ”Œ๋ž˜๊ทธ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ๋ชฉ๋ก 2์— ํ‘œ์‹œ๋œ ๊ฒƒ์ฒ˜๋Ÿผ "์ข…๋ฃŒํ•  ์ค€๋น„๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์‹คํ–‰" ํ˜•์‹์˜ ์ œ์–ด ๊ตฌ์„ฑ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. volatile boolean shutdownRequested; ... public void shutdown() { shutdownRequested = true; } public void doWork() { while (!shutdownRequested) { // do stuff } } shutdown() ๋ฉ”์„œ๋“œ๋Š” ๋ฃจํ”„ ์™ธ๋ถ€์˜ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ˜ธ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์˜ฌ๋ฐ”๋ฅธ ๋ณ€์ˆ˜ ๊ฐ€์‹œ์„ฑ shutdownRequested๋ฅผ ๋ณด์žฅํ•˜๋ ค๋ฉด ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. (JMX ๋ฆฌ์Šค๋„ˆ, GUI ์ด๋ฒคํŠธ ์Šค๋ ˆ๋“œ์˜ ์•ก์…˜ ๋ฆฌ์Šค๋„ˆ, RMI, ์›น ์„œ๋น„์Šค ๋“ฑ์„ ํ†ตํ•ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) ๊ทธ๋Ÿฌ๋‚˜ ๋™๊ธฐํ™”๋œ ๋ธ”๋ก์ด ์žˆ๋Š” ๋ฃจํ”„๋Š” ๋ชฉ๋ก 2์™€ ๊ฐ™์ด ํœ˜๋ฐœ์„ฑ ์ƒํƒœ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ๋Š” ๋ฃจํ”„๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ ์ž‘์„ฑ์ด ๋” ์‰ฌ์›Œ์ง€๊ณ  ์ƒํƒœ ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ๋‹ค์Œ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ์„ ์ž˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํƒœ ํ”Œ๋ž˜๊ทธ์˜ ํŠน์ง•์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒํƒœ ์ „ํ™˜์ด ํ•˜๋‚˜๋งŒ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. shutdownRequested ํ”Œ๋ž˜๊ทธ๊ฐ€ false์—์„œ true๋กœ ๋ฐ”๋€Œ๊ณ  ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ ์•ž๋’ค๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ ํ”Œ๋ž˜๊ทธ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์™ธ๋ถ€ ๊ฐœ์ž… ์—†์ด ์ „ํ™˜ ์ฃผ๊ธฐ(false์—์„œ true, false๋กœ)๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์›์ž ๋ณ€์ˆ˜์™€ ๊ฐ™์€ ์ผ์ข…์˜ ์›์ž ์ „ํ™˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
ํŒจํ„ด #2: ์ผํšŒ์„ฑ ๋ณด์•ˆ ๊ฒŒ์‹œ
๋™๊ธฐํ™”๊ฐ€ ์—†์„ ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์‹œ์„ฑ ์˜ค๋ฅ˜๋Š” ๊ธฐ๋ณธ ๊ฐ’ ๋Œ€์‹  ๊ฐœ์ฒด ์ฐธ์กฐ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ํ›จ์”ฌ ๋” ์–ด๋ ค์šด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™๊ธฐํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์„ฑํ•œ ๊ฐœ์ฒด ์ฐธ์กฐ์˜ ํ˜„์žฌ ๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ๊ฐœ์ฒด์˜ ์˜ค๋ž˜๋œ ์ƒํƒœ ๊ฐ’๋„ ๊ณ„์† ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ด ์œ„ํ˜‘์€ ๋™๊ธฐํ™” ์—†์ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ฝ๋Š” ์•…๋ช… ๋†’์€ ์ด์ค‘ ํ™•์ธ ์ž ๊ธˆ ๋ฌธ์ œ์˜ ๊ทผ๋ณธ ์›์ธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์‹ค์ œ ์ฐธ์กฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฅผ ํ†ตํ•ด ๋ถ€๋ถ„์ ์œผ๋กœ ๊ตฌ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ์–ป์„ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.) ๊ฐ์ฒด๋Š” ํœ˜๋ฐœ์„ฑ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Listing 3์€ ์‹œ์ž‘ํ•˜๋Š” ๋™์•ˆ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ์˜ˆ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ๋Š” ์‚ฌ์šฉ์„ ์‹œ๋„ํ•˜๊ธฐ ์ „์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฒŒ์‹œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. public class BackgroundFloobleLoader { public volatile Flooble theFlooble; public void initInBackground() { // ะดะตะปะฐะตะผ ะผะฝะพะณะพ ะฒััะบะพะณะพ theFlooble = new Flooble(); // ะตะดะธะฝัั‚ะฒะตะฝะฝะฐั ะทะฐะฟะธััŒ ะฒ theFlooble } } public class SomeOtherClass { public void doWork() { while (true) { // ั‡ั‘-ั‚ะพ ั‚ะฐะผ ะดะตะปะฐะตะผ... // ะธัะฟะพะปัŒะทัƒะตะผ theFolooble, ะฝะพ ั‚ะพะปัŒะบะพ ะตัะปะธ ะพะฝะฐ ะณะพั‚ะพะฒะฐ if (floobleLoader.theFlooble != null) doSomething(floobleLoader.theFlooble); } } } theFooble์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์ผ์‹œ์ ์ด์ง€ ์•Š์€ ๊ฒฝ์šฐ doWork()์˜ ์ฝ”๋“œ๋Š” theFlooble์„ ์ฐธ์กฐํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ถ€๋ถ„์ ์œผ๋กœ ์ƒ์„ฑ๋œ Flooble์„ ๋ณผ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์˜ ํ•ต์‹ฌ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๊ฒŒ์‹œ๋œ ๊ฐœ์ฒด๊ฐ€ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์‹ค์ƒ ๋ถˆ๋ณ€์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋ถˆ๋ณ€์ด๋ž€ ๊ฒŒ์‹œ๋œ ํ›„ ์ƒํƒœ๊ฐ€ ์ ˆ๋Œ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ์ฒด๊ฐ€ ๊ฒŒ์‹œ๋œ ํ˜•์‹์œผ๋กœ ํ‘œ์‹œ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฒŒ์‹œ ํ›„ ๊ฐœ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ถ”๊ฐ€ ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
ํŒจํ„ด #3: ๋…๋ฆฝ์ ์ธ ๊ด€์ฐฐ
ํœ˜๋ฐœ์„ฑ์„ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฐ„๋‹จํ•œ ์˜ˆ๋Š” ๊ด€์ฐฐ ๊ฒฐ๊ณผ๊ฐ€ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ๊ธฐ์ ์œผ๋กœ "๊ฒŒ์‹œ"๋˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ˜„์žฌ ์˜จ๋„๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ํ™˜๊ฒฝ ์„ผ์„œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋Š” ๋ช‡ ์ดˆ๋งˆ๋‹ค ์ด ์„ผ์„œ๋ฅผ ์ฝ๊ณ  ํ˜„์žฌ ์˜จ๋„๊ฐ€ ํฌํ•จ๋œ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์ด ๋ณ€์ˆ˜๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ทธ ๊ฐ’์ด ํ•ญ์ƒ ์ตœ์‹ ์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์˜ ๋˜ ๋‹ค๋ฅธ ์šฉ๋„๋Š” ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ํ†ต๊ณ„๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชฉ๋ก 4๋Š” ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋งˆ์ง€๋ง‰์œผ๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„์„ ๊ธฐ์–ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. lastUser ์ฐธ์กฐ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉํ•  ๊ฐ’์„ ๊ฒŒ์‹œํ•˜๋Š” ๋ฐ ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. public class UserManager { public volatile String lastUser; public boolean authenticate(String user, String password) { boolean valid = passwordIsValid(user, password); if (valid) { User u = new User(); activeUsers.add(u); lastUser = user; } return valid; } } ์ด ํŒจํ„ด์€ ์ด์ „ ํŒจํ„ด์„ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์€ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฒŒ์‹œ๋˜์ง€๋งŒ ๊ฒŒ์‹œ๋Š” ์ผํšŒ์„ฑ ์ด๋ฒคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ์ผ๋ จ์˜ ๋…๋ฆฝ์ ์ธ ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ฒŒ์‹œ๋œ ๊ฐ’์ด ํšจ๊ณผ์ ์œผ๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๊ฒŒ์‹œ ํ›„์— ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋Š” ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ธ์‹ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ํŒจํ„ด #4: "ํœ˜๋ฐœ์„ฑ ์ฝฉ" ํŒจํ„ด
"ํœ˜๋ฐœ์„ฑ ๋นˆ" ํŒจํ„ด์€ JavaBeans๋ฅผ "์˜๊ด‘ํ™”๋œ ๊ตฌ์กฐ์ฒด"๋กœ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์— ์ ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. "ํœ˜๋ฐœ์„ฑ ๋นˆ" ํŒจํ„ด์€ getter ๋ฐ/๋˜๋Š” setter๊ฐ€ ์žˆ๋Š” ๋…๋ฆฝ์ ์ธ ์†์„ฑ ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ปจํ…Œ์ด๋„ˆ๋กœ JavaBean์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. "ํœ˜๋ฐœ์„ฑ ๋นˆ" ํŒจํ„ด์˜ ์ด๋ก ์  ๊ทผ๊ฑฐ๋Š” ๋งŽ์€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ํ™€๋”(์˜ˆ: HttpSession)์— ๋Œ€ํ•œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ปจํ…Œ์ด๋„ˆ์— ๋ฐฐ์น˜๋œ ๊ฐœ์ฒด๋Š” ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ ๋นˆ ํŒจํ„ด์—์„œ ๋ชจ๋“  JavaBean ๋ฐ์ดํ„ฐ ์š”์†Œ๋Š” ํœ˜๋ฐœ์„ฑ์ด๋ฉฐ getter ๋ฐ setter๋Š” ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•˜๋Š” ๊ฒƒ ์ด์™ธ์˜ ๋…ผ๋ฆฌ๋ฅผ ํฌํ•จํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐ์ฒด ์ฐธ์กฐ์ธ ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„์˜ ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์‚ฌ์‹ค์ƒ ๋ถˆ๋ณ€์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (๋ฐฐ์—ด ์ฐธ์กฐ๊ฐ€ ํœ˜๋ฐœ์„ฑ์œผ๋กœ ์„ ์–ธ๋˜๋ฉด ์š”์†Œ ์ž์ฒด๊ฐ€ ์•„๋‹Œ ํ•ด๋‹น ์ฐธ์กฐ๋งŒ ํœ˜๋ฐœ์„ฑ ์†์„ฑ์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด ์ฐธ์กฐ ํ•„๋“œ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.) ๋ชจ๋“  ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ JavaBeans์˜ ์†์„ฑ๊ณผ ๊ด€๋ จ๋œ ๋ถˆ๋ณ€์ด๋‚˜ ์ œํ•œ์ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. . "ํœ˜๋ฐœ์„ฑ ๋นˆ" ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ JavaBean์˜ ์˜ˆ๊ฐ€ ๋ชฉ๋ก 5์— ํ‘œ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. @ThreadSafe public class Person { private volatile String firstName; private volatile String lastName; private volatile int age; public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } public void setAge(int age) { this.age = age; } }
๋”์šฑ ๋ณต์žกํ•œ ํœ˜๋ฐœ์„ฑ ํŒจํ„ด
์ด์ „ ์„น์…˜์˜ ํŒจํ„ด์€ ํœ˜๋ฐœ์„ฑ ์‚ฌ์šฉ์ด ํ•ฉ๋ฆฌ์ ์ด๊ณ  ๋ถ„๋ช…ํ•œ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์˜ ๋Œ€๋ถ€๋ถ„์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” ํœ˜๋ฐœ์„ฑ์ด ์„ฑ๋Šฅ์ด๋‚˜ ํ™•์žฅ์„ฑ ์ด์ ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด๋‹ค ๋ณต์žกํ•œ ํŒจํ„ด์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค. ๋ณด๋‹ค ๋ฐœ์ „๋œ ํœ˜๋ฐœ์„ฑ ํŒจํ„ด์€ ๋งค์šฐ ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์ •์„ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์บก์Šํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„์ฃผ ์ž‘์€ ๋ณ€๊ฒฝ์ด๋ผ๋„ ์ฝ”๋“œ๋ฅผ ์†์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค! ๋˜ํ•œ ๋” ๋ณต์žกํ•œ ํœ˜๋ฐœ์„ฑ ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ์ฃผ๋œ ์ด์œ ๋Š” ์„ฑ๋Šฅ์ด๋ฏ€๋กœ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์‹ค์ œ๋กœ ์˜๋„ํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ํ•„์š”์„ฑ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ด๋Ÿฌํ•œ ํŒจํ„ด์€ ๊ฐ€๋Šฅํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ๊ฐ€๋…์„ฑ์ด๋‚˜ ์œ ์ง€ ๊ด€๋ฆฌ ์šฉ์ด์„ฑ์„ ํฌ์ƒํ•˜๋Š” ์ ˆ์ถฉ์•ˆ์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์—„๊ฒฉํ•œ ์ธก์ • ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์•„๋งˆ๋„ ๋‚˜์œ ๊ฑฐ๋ž˜์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ฐ€์น˜ ์žˆ๋Š” ๊ฒƒ์„ ํฌ๊ธฐํ•˜๊ณ  ๊ทธ ๋Œ€๊ฐ€๋กœ ๋” ์ ์€ ๊ฒƒ์„ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
ํŒจํ„ด #5: ์ €๋ ดํ•œ ์ฝ๊ธฐ-์“ฐ๊ธฐ ์ž ๊ธˆ
์ง€๊ธˆ์ฏค์ด๋ฉด ํœ˜๋ฐœ์„ฑ์ด ์นด์šดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ์•ฝํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ž˜ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ++x๋Š” ๋ณธ์งˆ์ ์œผ๋กœ ์„ธ ๊ฐ€์ง€ ์ž‘์—…(์ฝ๊ธฐ, ์ถ”๊ฐ€, ์ €์žฅ)์„ ์ค„์—ฌ์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ํœ˜๋ฐœ์„ฑ ์นด์šดํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋ ค๊ณ  ํ•˜๋ฉด ์—…๋ฐ์ดํŠธ๋œ ๊ฐ’์„ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋ณด๋‹ค ์ฝ๊ธฐ ํšŸ์ˆ˜๊ฐ€ ํ›จ์”ฌ ๋” ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” ๋‚ด์žฅ ์ž ๊ธˆ ๋ฐ ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ „์ฒด ์ฝ”๋“œ ๊ฒฝ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Listing 6์—์„œ๋Š” ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฆ๋ถ„ ์ž‘์—…์ด ์›์ž์„ฑ์ธ์ง€ ํ™•์ธํ•˜๊ณ  ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ ๊ฒฐ๊ณผ๊ฐ€ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ ์นด์šดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ฝ๊ธฐ ๋น„์šฉ์ด ์ผ์‹œ์ ์ธ ์ฝ๊ธฐ๋กœ ์ œํ•œ๋˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ์ถฉ๋Œํ•˜์ง€ ์•Š๋Š” ์ž ๊ธˆ์„ ํš๋“ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ €๋ ดํ•˜๋ฏ€๋กœ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @ThreadSafe public class CheesyCounter { // Employs the cheap read-write lock trick // All mutative operations MUST be done with the 'this' lock held @GuardedBy("this") private volatile int value; public int getValue() { return value; } public synchronized int increment() { return value++; } } ์ด ๋ฐฉ๋ฒ•์„ "์ €๋ ดํ•œ ์ฝ๊ธฐ-์“ฐ๊ธฐ ์ž ๊ธˆ"์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ด์œ ๋Š” ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ์— ์„œ๋กœ ๋‹ค๋ฅธ ํƒ€์ด๋ฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์“ฐ๊ธฐ ์ž‘์—…์€ ํœ˜๋ฐœ์„ฑ ์‚ฌ์šฉ์˜ ์ฒซ ๋ฒˆ์งธ ์กฐ๊ฑด์„ ์œ„๋ฐ˜ํ•˜๋ฏ€๋กœ ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์นด์šดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ์„ ๋•Œ ํ˜„์žฌ ๊ฐ’์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ์ˆ˜์ • ์ž‘์—…์—๋Š” ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ์ฝ๊ธฐ ์ „์šฉ ์ž‘์—…์—๋Š” ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ฐ’์— ์•ก์„ธ์Šคํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํœ˜๋ฐœ์„ฑ ์ฝ๊ธฐ๋Š” ๋‘˜ ์ด์ƒ์˜ ์ฝ๊ธฐ๋ฅผ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ ์ฝ๊ธฐ๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์ฝ”๋“œ์— ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•  ๋•Œ๋ณด๋‹ค ๋” ๋†’์€ ์ˆ˜์ค€์˜ ๊ตํ™˜์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ๊ณ  ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ํŒจํ„ด์˜ ์ทจ์•ฝ์„ฑ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ๋‘ ๊ฐ€์ง€ ๊ฒฝ์Ÿ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ํŒจํ„ด์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„œ๋ฉด ๋งค์šฐ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์š”์•ฝ
ํœ˜๋ฐœ์„ฑ ๋ณ€์ˆ˜๋Š” ์ž ๊ธˆ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜์ง€๋งŒ ์•ฝํ•œ ํ˜•ํƒœ์˜ ๋™๊ธฐํ™”๋กœ, ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๋‚ด์žฅ ์ž ๊ธˆ๋ณด๋‹ค ๋” ๋‚˜์€ ์„ฑ๋Šฅ์ด๋‚˜ ํ™•์žฅ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํœ˜๋ฐœ์„ฑ์˜ ์•ˆ์ „ํ•œ ์‚ฌ์šฉ์„ ์œ„ํ•œ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•˜๋Š” ๊ฒฝ์šฐ(๋ณ€์ˆ˜๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜ ๋ฐ ์ด์ „ ๊ฐ’ ๋ชจ๋‘์™€ ์‹ค์ œ๋กœ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค) ๋•Œ๋•Œ๋กœ ๋™๊ธฐํ™”๋ฅผ ํœ˜๋ฐœ์„ฑ์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํœ˜๋ฐœ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ณด๋‹ค ์ทจ์•ฝํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ œ์•ˆ๋œ ํŒจํ„ด์€ ๋ณ€๋™์„ฑ์ด ๋™๊ธฐํ™”์— ๋Œ€ํ•œ ํ•ฉ๋ฆฌ์ ์ธ ๋Œ€์•ˆ์ธ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ณ  ํ•œ๊ณ„๋ฅผ ์ดˆ๊ณผํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•จ์œผ๋กœ์จ ์ด์ ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ํœ˜๋ฐœ์„ฑ์„ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝ”๋ฉ˜ํŠธ
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION