Skip to content

Latest commit

ย 

History

History
252 lines (172 loc) ยท 13.9 KB

File metadata and controls

252 lines (172 loc) ยท 13.9 KB

item 78 : ๊ณต์œ  ์ค‘์ธ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋Š” ๋™๊ธฐํ™”ํ•ด ์‚ฌ์šฉํ•˜๋ผ

Synchronized ํ‚ค์›Œ๋“œ์™€ ๋™๊ธฐํ™”์˜ ์ค‘์š”์„ฑ

๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์„ ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋ณด์žฅํ•˜๋ ค๋ฉด synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋™๊ธฐํ™”๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๋ฉ”์„œ๋“œ๋„ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์€ ์ˆœ๊ฐ„์„ ๋ณผ ์ˆ˜ ์—†๋‹ค. ๋™๊ธฐํ™”๋œ ๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์— ๋“ค์–ด๊ฐ„ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ๋ฝ์˜ ๋ณดํ˜ธํ•˜์— ์ˆ˜ํ–‰๋œ ๋ชจ๋“  ์ด์ „ ์ˆ˜์ •์˜ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๊ฐ™๊ฒŒ ํ•œ๋‹ค. ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋ฉด ๋™๊ธฐํ™”๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์•„๋„ ๋˜์ง€๋งŒ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜์ด๋ผ๋ฉด ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•  ๋•Œ ๋™๊ธฐํ™”๋ฅผ ๊ณ ๋ฏผํ•ด์•ผ ํ•œ๋‹ค.

1. Synchronized์˜ ๊ธฐ๋ณธ ๋™์ž‘

  • Synchronized ํ‚ค์›Œ๋“œ๋Š” ๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์„ ํ•œ ๋ฒˆ์— ํ•œ ์Šค๋ ˆ๋“œ์”ฉ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค.
  • ๋™๊ธฐํ™”์˜ ์ฃผ์š” ๋ชฉ์ :
    • ๋ฐฐํƒ€์  ์‹คํ–‰: ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์€ ์ƒํƒœ์˜ ๊ฐ์ฒด๋ฅผ ๋ณด์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๋Š”๋‹ค.
    • ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹  ๋ณด์žฅ: ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋งŒ๋“  ๋ณ€ํ™”๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

๋™๊ธฐํ™”๋Š” ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋งค์šฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค. ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ , ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ํ•„์ˆ˜์ ์ด๋‹ค. ๋™๊ธฐํ™”๊ฐ€ ์—†๋‹ค๋ฉด, ํ”„๋กœ๊ทธ๋žจ์ด ์˜๋„ํ•˜์ง€ ์•Š์€ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์ง€๊ณ , ๋””๋ฒ„๊น…์ด ๊ทน๋„๋กœ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค. ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ํ†ต์‹ ๊ณผ ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ๋ถˆํ™•์‹คํ•  ๋•Œ, ๋™๊ธฐํ™”๋Š” ์•ˆ์ •์„ฑ๊ณผ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค.

ํŠนํžˆ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜์™€ ๊ฒฝ์Ÿ ์ƒํƒœ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์‹ ๋ขฐ์„ฑ๊ณผ ์•ˆ์ „์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

2. ๋™๊ธฐํ™”์™€ ์ž๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ

1) ์›์ž์  ๋™์ž‘

  • long๊ณผ double์„ ์ œ์™ธํ•œ ๋ณ€์ˆ˜์˜ ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ๋™์ž‘์€ ์›์ž์ ์ด๋‹ค.
    • ์ฆ‰, ๋™๊ธฐํ™” ์—†์ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜๋”๋ผ๋„ ํ•ญ์ƒ ์–ด๋–ค ์Šค๋ ˆ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ €์žฅํ•œ ๊ฐ’์„ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์›์ž์„ฑ ๋ณด์žฅ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค. ํ•œ ์Šค๋ ˆ๋“œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ด€์ฐฐ๋  ์‹œ์ ์€ ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.

ํ’€์–ด์„œ ๋งํ•ด๋ณด์ž๋ฉด, ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•„๋“œ๋ฅผ ์ฝ์„ ๋•Œ ํ•ญ์ƒ โ€˜์ˆ˜์ •์ด ์™„์ „ํžˆ ๋ฐ˜์˜๋œโ€™ ๊ฐ’์„ ์–ป๋Š”๋‹ค ๋ณด์žฅํ•˜์ง€๋งŒ, ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ €์žฅํ•œ ๊ฐ’์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ โ€˜๋ณด์ด๋Š”๊ฐ€โ€™๋Š” ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์›์ž์  ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ๋•Œ๋„ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ์‹œ: ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ด์„œ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ํ†ต์‹ ์ด ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋™๊ธฐํ™”๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๊ณต์œ ํ•˜๋„๋ก ๋•๋Š”๋‹ค.

2) ๋™๊ธฐํ™”์˜ ํ•„์š”์„ฑ

  • ๋™๊ธฐํ™” ์—†์ด ์›์ž์  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ๊ฒฝ์šฐ ์น˜๋ช…์  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Thread.stop() ๋ฉ”์„œ๋“œ์˜ ์‚ฌ๋ก€๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
    • Thread.stop() ๋ฉ”์„œ๋“œ๋Š” ์•ˆ์ „ํ•˜์ง€ ์•Š์•„ ์ด๋ฏธ ์‚ฌ์šฉ ์ž์ œ(deprecated) API๋กœ ์ง€์ •๋˜์—ˆ๋‹ค.
    • ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ•์ œ๋กœ ์ˆ˜์ •ํ•˜๋ฉฐ ์Šค๋ ˆ๋“œ ๊ฐ„ ์ผ๊ด€์„ฑ์„ ๊นจํŠธ๋ฆด ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

๋”ฐ๋ผ์„œ, ์Šค๋ ˆ๋“œ๋ฅผ ๋ฉˆ์ถ”๋Š” ์ž‘์—…์กฐ์ฐจ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋™๊ธฐํ™”๋œ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณดํ˜ธํ•˜๊ณ , ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹ ์˜ ์‹ ๋ขฐ์„ฑ์„ ํ™•๋ณดํ•ด์•ผ ํ•œ๋‹ค.

3. ์ž˜๋ชป๋œ ์ฝ”๋“œ ์˜ˆ์‹œ

๋™๊ธฐํ™”๊ฐ€ ์ž˜๋ชป ๋˜์—ˆ์„ ๋•Œ๋Š” ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด์ž. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์–ผ๋งˆ๋‚˜ ์˜ค๋žซ๋™์•ˆ ์‹คํ–‰๋ ๊นŒ?

1) ๋ฌธ์ œ ์ฝ”๋“œ

public class StopThread {
    private static boolean stopRequested;

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(() -> {
            int i = 0;
            while (!stopRequested) {
                i++;
            }
        });
        backgroundThread.start();

        TimeUnit.SECONDS.sleep(1);
        stopRequested = true;
    }
}
  • ๋ฌธ์ œ์ :
    • ์Šค๋ ˆ๋“œ๊ฐ€ start ๋˜๊ณ  1์ดˆ ๋™์•ˆ์˜ sleep์ด ๋๋‚˜๋ฉด boolean ๋ณ€์ˆ˜์˜ ๊ฐ’์ด true๊ฐ€ ๋˜์–ด ๋ฃจํ”„๋ฅผ ๋น ์ ธ๋‚˜์˜ฌ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•ด๋ณด๋ฉด ํ”„๋กœ๊ทธ๋žจ์€ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค.
    • ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ stopRequested = true;๋กœ ์„ค์ •ํ•ด๋„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด๋ฅผ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ด๋Š” ๋™๊ธฐํ™”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ๊ฐ€์ƒ ๋จธ์‹ ์˜ ์ตœ์ ํ™”๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์‹œ ์ตœ์ ํ™”:

// ์›๋ž˜ ์ฝ”๋“œ
while (!stopRequested) i++;

// ์ตœ์ ํ™”๋œ ์ฝ”๋“œ
if (!stopRequested) {
    while (true) i++;
}
  • ์ด๋Š” JVM์ด ์‹ค์ œ๋กœ ์ ์šฉํ•˜๋Š” ๋Œ์–ด์˜ฌ๋ฆฌ๊ธฐ(hoisting, ํ˜ธ์ด์ŠคํŒ…)๋ผ๋Š” ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋œ ๊ฒƒ์ด๋‹ค.
  • ์ด์™€ ๊ฐ™์€ ์ตœ์ ํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์€ ์‘๋‹ต ๋ถˆ๊ฐ€ ์ƒํƒœ(liveness failure)๊ฐ€ ๋˜์–ด ์ข…๋ฃŒ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

2) ์ˆ˜์ •๋œ ์ฝ”๋“œ

.๋‹ค์‹œ ๊ธฐ์กด ์ฝ”๋“œ๋กœ ๋Œ์•„์™€์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด, ๊ณต์œ ํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ๋™๊ธฐํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

public class StopThread {
    private static boolean stopRequested;

    private static synchronized void requestStop() {
        stopRequested = true;
    }

    private static synchronized boolean stopRequested() {
        return stopRequested;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(() -> {
            int i = 0;
            while (!stopRequested()) {
                i++;
            }
        });
        backgroundThread.start();

        TimeUnit.SECONDS.sleep(1);
        requestStop();
    }
}
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:
    • requestStop๊ณผ stopRequested๋ฅผ ๋ชจ๋‘ ๋™๊ธฐํ™”ํ•˜์—ฌ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ํ†ต์‹ ์„ ๋ณด์žฅ.
    • ์ด๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์„œ๋กœ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

๋™๊ธฐํ™”๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ƒํƒœ๋ฅผ ๋ช…ํ™•ํžˆ ์ •์˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋™์ž‘ ์˜ˆ์ธก์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ๋””๋ฒ„๊น… ํŽธ์˜์„ฑ ๋˜ํ•œ ์ฆ๊ฐ€ํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ ๋™๊ธฐํ™”๋Š” ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ์— ๋Œ€ํ•ด ๋ชจ๋‘ ํ•„์š”ํ•˜๋‹ค. ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๊ณต์œ  ํ•„๋“œ์— ๋Œ€ํ•œ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ฉ”์„œ๋“œ ๋ชจ๋‘๋ฅผ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌํ•˜๋ฉด ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋œ๋‹ค.

3) ๊ฐœ์„ ๋œ ์ฝ”๋“œ (volatile ์‚ฌ์šฉ)

public class StopThread {
    private static volatile boolean stopRequested;

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(() -> {
            int i = 0;
            while (!stopRequested) {
                i++;
            }
        });
        backgroundThread.start();

        TimeUnit.SECONDS.sleep(1);
        stopRequested = true;
    }
}
  • volatile ํ•œ์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™๊ธฐํ™” ์—†์ด๋„ ์ตœ์‹  ๊ฐ’ ๋ณด์žฅ. ์ด๋ก ์ ์œผ๋กœ๋Š” CPU ์บ์‹œ๊ฐ€ ์•„๋‹Œ ์ปดํ“จํ„ฐ์˜ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์ฝ์–ด์˜จ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ชจ๋‘๊ฐ€ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ˆ˜ํ–‰๋œ๋‹ค.
  • volatile์€ ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹  ๋ณด์žฅ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๋ฐฐํƒ€์  ์‹คํ–‰์€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ถ”๊ฐ€ ์„ค๋ช…: volatile์€ ์ ์ ˆํ•œ ์‚ฌ์šฉ ์‹œ ์„ฑ๋Šฅ๊ณผ ๊ฐ„๊ฒฐ์„ฑ์„ ๋ชจ๋‘ ์ œ๊ณตํ•˜์ง€๋งŒ, ๋ชจ๋“  ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋ฐฐํƒ€์  ์‹คํ–‰์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

4. ์ž˜๋ชป๋œ ๋™๊ธฐํ™”์™€ ์›์ž์„ฑ ๋ฌธ์ œ

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ volatile์„ ์‚ฌ์šฉํ•˜๋ฉด ๋™๊ธฐํ™”๋ฅผ ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค. ๋‹ค๋งŒ ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ˆ์ œ์—์„œ ๋ฌธ์ œ์ ์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

1) ์ฆ๊ฐ€ ์—ฐ์‚ฐ์ž(++)์˜ ๋ฌธ์ œ

private static volatile int nextSerialNumber = 0;

public static int generateSerialNumber() {
    return nextSerialNumber++;
}
  • ๋ฌธ์ œ์ :
    • ์ฝ”๋“œ์ƒ์œผ๋กœ ์ฆ๊ฐ€ ์—ฐ์‚ฐ์ž(++)๋Š” ํ•˜๋‚˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” volatile ํ•„๋“œ์— ๋‘ ๋ฒˆ ์ ‘๊ทผํ•œ๋‹ค. ๋จผ์ € ๊ฐ’์„ ์ฝ๊ณ , ๊ทธ ๋‹ค์Œ์— 1์„ ์ฆ๊ฐ€ํ•œ ํ›„ ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ์˜ ์—ฐ์‚ฐ ์‚ฌ์ด์— ๋“ค์–ด์™€ ๊ณต์œ  ํ•„๋“œ๋ฅผ ์ฝ๊ฒŒ ๋˜๋ฉด, ์ฒซ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ์™€ ๊ฐ™์€ ๊ฐ’์„ ๋ณด๊ฒŒ๋  ๊ฒƒ์ด๋‹ค.
    • ์ฆ๊ฐ€ ์—ฐ์‚ฐ์ž(++)๋Š” ์›์ž์ ์ด์ง€ ์•Š์Œ.
    • ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ์‚ฌ์ด์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐœ์ž…ํ•  ๊ฐ€๋Šฅ์„ฑ.

์ด๋กœ ์ธํ•ด ๋™์ผํ•œ ๊ฐ’์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜ํ™˜๋˜๋Š” ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•ด๋‚ด๋Š” ์˜ค๋ฅ˜๋ฅผ ์•ˆ์ „ ์‹คํŒจ(safety failure)๋ผ๊ณ  ํ•œ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ๋ฉ”์„œ๋“œ์— synchronized๋ฅผ ๋ถ™์ด๊ณ  volatile ํ‚ค์›Œ๋“œ๋ฅผ ๊ณต์œ  ํ•„๋“œ์—์„œ ์ œ๊ฑฐํ•˜๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.

2) ์˜ฌ๋ฐ”๋ฅธ ๋™๊ธฐํ™” ์ฝ”๋“œ(atomic ํŒจํ‚ค์ง€)

private static final AtomicLong nextSerialNum = new AtomicLong();

public static long generateSerialNumber() {
    return nextSerialNum.getAndIncrement();
}
  • java.util.concurrent.atomic ํŒจํ‚ค์ง€์˜ AtomicLong์„ ์‚ฌ์šฉ.
    • ๋ฝ-ํ”„๋ฆฌ(lock-free) ๋ฐฉ์‹์œผ๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „ ๊ตฌํ˜„.
    • ์„ฑ๋Šฅ ๋ฉด์—์„œ๋„ ์šฐ์ˆ˜.
    • AtomicLong์˜ ์žฅ์ : ๋ณ„๋„์˜ ๋ฝ(lock)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•œ ํ™˜๊ฒฝ์—์„œ ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    • volatile์€ ๋™๊ธฐํ™”์˜ ํšจ๊ณผ ์ค‘ ํ†ต์‹  ์ชฝ๋งŒ ์ง€์›ํ•˜์ง€๋งŒ ์ด ํŒจํ‚ค์ง€๋Š” ์›์ž์„ฑ(๋ฐฐํƒ€์  ์‹คํ–‰)๊นŒ์ง€ ์ง€์›ํ•œ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์„ฑ๋Šฅ๋„ ๋™๊ธฐํ™” ๋ฒ„์ „๋ณด๋‹ค ์šฐ์ˆ˜ํ•˜๋‹ค.

3) ๋™๊ธฐํ™” ๋ฐฉ์‹ ๋น„๊ต

  • synchronized์™€ AtomicLong:
    • synchronized๋Š” ๋ฐฐํƒ€์  ์‹คํ–‰๊ณผ ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹ ์„ ๋ชจ๋‘ ๋ณด์žฅํ•˜์ง€๋งŒ, ์„ฑ๋Šฅ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋‚ฎ๋‹ค.
    • AtomicLong์€ ๊ฐ€๋ฒผ์šด ๋ฝ-ํ”„๋ฆฌ ๋ฐฉ์‹์œผ๋กœ, ๋™์‹œ์„ฑ ์ž‘์—…์—์„œ ๋” ๋†’์€ ์„ฑ๋Šฅ ์ œ๊ณต.

๋ถ€๊ฐ€ ์„ค๋ช…: synchronized๋Š” ์ฝ”๋“œ์˜ ๋™์ž‘ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜์ง€๋งŒ, ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด AtomicLong์€ ์ด๋Ÿฌํ•œ ๋ณ‘๋ชฉ์„ ์ตœ์†Œํ™”ํ•˜๋ฉฐ ๋” ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ œ๊ณตํ•œ๋‹ค.

5. ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ์™€ ๋™๊ธฐํ™” ์ •์ฑ…

  • ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•: ๊ณต์œ  ์ค‘์ธ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์†Œํ™”.
    • ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ(immutable)๋งŒ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜, ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉ.

1) ์•ˆ์ „ ๋ฐœํ–‰(Safe Publication)

  • ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ๋•Œ๋Š” ์•ˆ์ „ ๋ฐœํ–‰ ๊ธฐ๋ฒ• ์‚ฌ์šฉ.
    • ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•˜๊ฒŒ ์ „๋‹ฌ.
    • ์•ˆ์ „ ๋ฐœํ–‰์€ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๋ฉฐ, ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค.

2) ์•ˆ์ „ ๋ฐœํ–‰ ๋ฐฉ๋ฒ•

  • ๊ฐ์ฒด๋ฅผ ๋‹ค์Œ ์œ„์น˜์— ์ €์žฅ:
    • ์ •์  ํ•„๋“œ
    • volatile ํ•„๋“œ
    • final ํ•„๋“œ
    • ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜
  • ๊ฐ ์ €์žฅ ์œ„์น˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฐ€์‹œ์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.

3) ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜ ์‚ฌ์šฉ

  • java.util.concurrent ํŒจํ‚ค์ง€์˜ ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜ ์‚ฌ์šฉ:
    • ConcurrentHashMap, CopyOnWriteArrayList ๋“ฑ.
    • ๋ฝ ์—†์ด๋„ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ ์ œ๊ณต.

์ฃผ์˜: ์™ธ๋ถ€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋™์ž‘๋„ ์ž˜ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

  • ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์Šค๋ ˆ๋“œ ๊ฐ„ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์„œ๋ฅผ ๊ผผ๊ผผํžˆ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
  • ์ฃผ์˜: ๋™์‹œ์„ฑ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ๋ฐ์ดํ„ฐ์˜ ๋…ผ๋ฆฌ์  ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์—ฌ์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ ์ปฌ๋ ‰์…˜์— ๊ฑธ์นœ ์ž‘์—…์€ ๋ณ„๋„์˜ ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“š ํ•ต์‹ฌ ์ •๋ฆฌ

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋ฉด ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๋Š” ๋™์ž‘์€ ๋ฐ˜๋“œ์‹œ ๋™๊ธฐํ™” ํ•ด์•ผ ํ•œ๋‹ค. Synchronized์™€ volatile์€ ์ž๋ฐ”์˜ ๋™๊ธฐํ™”์—์„œ ํ•„์ˆ˜์ ์ด๋‹ค.

  • ๋™๊ธฐํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆ˜ํ–‰ํ•œ ๋ณ€๊ฒฝ์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณด์ง€ ๋ชปํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค. ๊ณต์œ ๋˜๋Š” ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋Š” ๋ฐ ์‹คํŒจํ•˜๋ฉด ์‘๋‹ต ๋ถˆ๊ฐ€ ์ƒํƒœ์— ๋น ์ง€๊ฑฐ๋‚˜ ์•ˆ์ „ ์‹คํŒจ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Š” ๋””๋ฒ„๊น… ๋‚œ์ด๋„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋ฌธ์ œ์— ์†ํ•œ๋‹ค. ๊ฐ„ํ—์ ์ด๊ฑฐ ๋‚˜ ํŠน์ • ํƒ€์ด๋ฐ์—๋งŒ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๊ณ , VM์— ๋”ฐ๋ผ ํ˜„์ƒ์ด ๋‹ฌ๋ผ์ง€๊ธฐ๋„ ํ•œ๋‹ค. ๋ฐฐํƒ€์  ์‹คํ–‰์€ ํ•„์š” ์—†๊ณ  ์Šค๋ ˆ๋“œ๋ผ๋ฆฌ์˜ ํ†ต์‹ ๋งŒ ํ•„์š”ํ•˜๋‹ค๋ฉด volatile ํ•œ์ •์ž๋งŒ์œผ๋กœ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ ์˜ฌ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๊นŒ๋‹ค๋กญ๋‹ค.
  • ๊ฐ ๋„๊ตฌ์˜ ์—ญํ• ๊ณผ ์‚ฌ์šฉ๋ฒ•์„ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๋ฉด, ๋ณด๋‹ค ์•ˆ์ „ํ•˜๊ณ  ํšจ์œจ์ ์ธ ํ”„๋กœ๊ทธ๋žจ์„ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.\

์ฐธ๊ณ  ๋ฐ ์ถœ์ฒ˜