DevLog ๐Ÿ˜ถ

[์ดํŒฉํ‹ฐ๋ธŒ์ž๋ฐ”] ์•„์ดํ…œ 78. ๊ณต์œ  ์ค‘์ธ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋Š” ๋™๊ธฐํ™”ํ•ด ์‚ฌ์šฉํ•˜๋ผ (1) ๋ณธ๋ฌธ

๐Ÿ“–/Effective Java

[์ดํŒฉํ‹ฐ๋ธŒ์ž๋ฐ”] ์•„์ดํ…œ 78. ๊ณต์œ  ์ค‘์ธ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋Š” ๋™๊ธฐํ™”ํ•ด ์‚ฌ์šฉํ•˜๋ผ (1)

dolmeng2 2023. 3. 26. 21:24

๐Ÿ’ฌ ์ดํŒฉํ‹ฐ๋ธŒ์ž๋ฐ” ์•„์ดํ…œ 78์„ ์ฝ๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ์ •๋ฆฌ๋Š” ์ฑ…๊ณผ๋Š” ๋‹ค์†Œ ๋‹ค๋ฅธ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค :D 

๊ฐœ๋… ์ž์ฒด๊ฐ€ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด์–ด์„œ ์ฑ…์„ ์ฝ์œผ๋ฉฐ ๊ถ๊ธˆํ•œ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์กฐ์‚ฌํ•˜๋Š” ์‹์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค ๐Ÿ™‡‍โ™€๏ธ

๋‘ ํŽธ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ํฌ์ŠคํŒ… ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค! 

์•„์ง ๋ฏธํกํ•œ ์ ์ด ๋งŽ์•„์„œ, ๋” ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์•Œ๊ฒŒ ๋˜๋ฉด ๋ณธ ๊ฒŒ์‹œ๊ธ€์„ ์ˆ˜์ •ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.


โœ”๏ธ ๋™๊ธฐํ™”๋ž€ ๋ฌด์—‡์ผ๊นŒ?

ํ˜„์žฌ ์ž”์•ก์ด 10000์›์ด๊ณ , ๊ฐ๊ฐ 1000์›์”ฉ ์ž…๊ธˆํ•˜๋Š” ํ–‰์œ„๋ฅผ 5000๋ฒˆ, 1000์›์”ฉ ์ถœ๊ธˆํ•˜๋Š” ํ–‰์œ„๋ฅผ 5000๋ฒˆ ๋ฐ˜๋ณตํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ๋™์ผํ•œ ๊ธˆ์•ก์— ๋Œ€ํ•ด ๋™์ผํ•œ ํšŸ์ˆ˜๋กœ 5000๋ฒˆ์”ฉ ์ง„ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์šฐ๋ฆฌ์˜ ์ž”์•ก์—๋Š” ๋ณ€ํ™”๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[synchronized ํ‚ค์›Œ๋“œ ๋ถ™์ด๊ธฐ ์ „]

public class Main {
    public static void main(String[] args) {
        Bank bank = new Bank();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                bank.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                bank.decrement();
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(bank.getMoney());
    }

    public static class Bank {
        private int money = 10000;

        public void increment() {
            money += 1000;
        }

        public void decrement() {
            money -= 1000;
        }

        public int getMoney() {
            return money;
        }
    }
}

๊ทธ๋Ÿฌ๋‚˜, ์šฐ๋ฆฌ์˜ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ด์ƒํ•œ ๊ฐ’์ด ํŠ€์–ด๋‚˜์˜จ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์‹ฌ์ง€์–ด, ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜จ๋‹ค.

 

์—ฌ๊ธฐ์„œ, ๊ฐœ์ธ์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์‹คํ—˜์„ ํ•˜๋ฉด์„œ ์‹ ๊ธฐํ–ˆ๋˜ ์ ์ด ์žˆ์—ˆ๋‹ค.

๋ฐ˜๋ณต๋ฌธ์„ ๋ช‡ ๋ฒˆ ๋„๋Š”์ง€์— ๋”ฐ๋ผ์„œ๋„ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐˆ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ˜๋ณต๋ฌธ์„ ๊ฐ๊ฐ 1000๋ฒˆ์”ฉ ๋Œ๊ฒŒ ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š”๋Œ€๋กœ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด๋‹ค. ์™œ์ง€? (์—ฌ๋Ÿฌ ๋ฒˆ ๋Œ๋ ธ๋Š”๋ฐ๋„ ๊ณ„์† ์ด๋ ‡๊ฒŒ ๋‚˜์™”๋‹ค ใ… ใ… )

 

๋‚ด ์ƒ๊ฐ์œผ๋กœ ๋ฃจํ”„์˜ ํšŸ์ˆ˜ ์ž์ฒด๋Š” thread-safe์— ์˜ํ–ฅ์„ ์ฃผ์ง€๋Š” ์•Š์„ ๊ฒƒ์ด๋‹ค.

์•„๋งˆ ๋ฐ˜๋ณต๋ฌธ์˜ ํšŸ์ˆ˜๊ฐ€ ์ ๋‹ค ๋ณด๋‹ˆ๊นŒ ์Šค๋ ˆ๋“œ๊ฐ€ ์šฐ์—ฐ์˜ ์ผ์น˜๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์ž˜ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ์Šค์ผ€์ค„๋ง์ด ๋˜์—ˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. (์ด๊ฒŒ JVM ↔ OS ์‚ฌ์ด์˜ ์Šค์ผ€์ค„๋ง์€ ํ™˜๊ฒฝ๋งˆ๋‹ค ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด ๋…ธํŠธ๋ถ์ด ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋…ธํŠธ๋ถ์ด์—ˆ์œผ๋ฉด 1000๋ฒˆ์„ ๋Œ๋ ค๋„ thread-safe ํ•˜์ง€ ์•Š๊ฒŒ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ๊ณ , 5000๋ฒˆ์„ ๋Œ๋ ค๋„ thread-safe ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

๊ฐ™์ด ์Šคํ„ฐ๋””๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ทธ๋ ˆ์ด๋„ ๋‹ค๋ฅด๊ฒŒ ๋‚˜์™”๋‹ค๊ณ  ํ•œ ๊ฒƒ์„ ๋ณด์•„, OS ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค!

 

๋‹ค์‹œ ๋Œ์•„๊ฐ€์„œ, ์™œ ์ €๋Ÿฐ ์š”์ƒํ•œ ๊ฐ’์ด ํŠ€์–ด๋‚˜์™”๋Š”์ง€ ๊ณ ๋ฏผํ•ด๋ณด์ž.

 

money -= 1000;

 

์ด ์ฝ”๋“œ๋Š” ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด ๋‹จ์ˆœํžˆ 1000์”ฉ ๊ฐ’์ด ๊ฐ์†Œํ•˜๋Š” ๋กœ์ง๋งŒ ์‹คํ–‰๋  ๊ฒƒ ๊ฐ™์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์ด 3๊ฐ€์ง€์˜ ์—ฐ์‚ฐ์ด ์‹คํ–‰๋œ๋‹ค.

1. ‘money’ ๋ณ€์ˆ˜๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฝ๋Š”๋‹ค.
2. ์ฝ์€ ‘money’ ๋ณ€์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.
3. ์—…๋ฐ์ดํŠธ๋œ ‘money’ ๋ณ€์ˆ˜๋ฅผ ๋‹ค์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์“ด๋‹ค.

์‹ค์ œ๋กœ ๋ฐ”์ดํŠธ์ฝ”๋“œ์˜ ์ผ๋ถ€๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

GETFIELD๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ISUB์„ ํ†ตํ•ด์„œ ๊ฐ’์„ ๋นผ๊ณ , ๋บ€ ๊ฐ’์„ ๋‹ค์‹œ PUTFIELD์œผ๋กœ ์“ฐ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

์œ„์˜ ์ƒํ™ฉ์— ํ•ด๋‹นํ•˜๋Š” ๊ทธ๋ฆผ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ทธ๋ ค๋ณด์•˜๋‹ค. ๋‘ ์Šค๋ ˆ๋“œ๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

์šฐ๋ฆฌ๋Š” ์Šค๋ ˆ๋“œ 1์ด ๊ฐ’์„ ๋บ€ ๋‹ค์Œ์— ์Šค๋ ˆ๋“œ 2๊ฐ€ ๊ฐ’์„ ์ฝ๊ธฐ๋ฅผ ์›ํ–ˆ๊ฒ ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์Šค๋ ˆ๋“œ 1์ด Money๋ผ๋Š” ๋ณ€์ˆ˜์— ์ฝ๊ณ , ๋บ€ ๋‹ค์Œ์— ๊ฐ’์„ ๋‹ค์‹œ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์ „์— ์Šค๋ ˆ๋“œ 2๊ฐ€ ๊ฐ’์„ ์ฝ๊ฒŒ ๋˜๋ฉด ๋‘ ์Šค๋ ˆ๋“œ ๋ชจ๋‘ '10000'์ด๋ผ๋Š” ๊ฐ’์„ ์ฝ๊ฒŒ ๋œ๋‹ค. 

์„œ๋กœ ํƒ€์ด๋ฐ์ด ์ข‹์ง€ ์•Š๊ฒŒ ๊ฐ’์„ ์ฝ๊ณ , ์“ฐ๋‹ค ๋ณด๋‹ˆ๊นŒ ์œ„์™€ ๊ฐ™์ด ์ด์ƒํ•œ ๊ฐ’์ด ๋„์ถœ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด, ์–ด๋–ป๊ฒŒ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์šฐ๋ฆฌ๋Š” synchronized๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

synchronized ํ‚ค์›Œ๋“œ๋Š” ๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์„ ํ•œ ๋ฒˆ์— ํ•œ ์Šค๋ ˆ๋“œ์”ฉ๋งŒ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค.

 

[synchronized ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ธ ํ›„]

public class Main {
    public static void main(String[] args) {
        Bank bank = new Bank();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                bank.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                bank.decrement();
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(bank.getMoney());
    }

    public static class Bank {
        private int money = 10000;

        public synchronized void increment() {
            money += 1000;
        }

        public synchronized void decrement() {
            money -= 1000;
        }

        public int getMoney() {
            return money;
        }
    }
}

ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”์„œ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋„ ์ผ๊ด€๋˜๊ณ  ๊ณต์œ  ๋ณ€์ˆ˜์— ๋Œ€ํ•ด์„œ๋„ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ ‘๊ทผ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋•๋ถ„์— ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰์„ ๊ฑฐ์น˜๋”๋ผ๋„ ๊ณ„์† 10000์ด๋ผ๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋ณด์žฅ๋œ๋‹ค.

 

๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

์•„๊นŒ์™€ ๋‹ค๋ฅด๊ฒŒ synchronized๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์‹ค ๊ทธ์™ธ ๋ฐ”์ดํŠธ ์ฝ”๋“œ์˜ ์ฐจ์ด๋Š” ๊ฑฐ์˜ ๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ synchronized ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ๋„ฃ๊ณ  ์•Œ์•„์„œ ๋ฝ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จ๋œ๋‹ค.

 

์šฐ๋ฆฌ๋Š” ์ด๋ ‡๊ฒŒ ์ˆœ์ฐจ์ ์œผ๋กœ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์„ ‘๋™๊ธฐํ™”ํ•œ๋‹ค’๋ผ๊ณ  ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ผ์ข…์˜ lock์„ ๊ฑด๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ž๋ฐ”์˜ Lock ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฃผ์„์ด ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค. (synchronized๊ฐ€ ์ž๋ฐ”์˜ Lock ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค! ๊ทธ์ €, ๋น„์Šทํ•œ ๊ฐœ๋…์ด๊ธฐ ๋•Œ๋ฌธ์— ์„ค๋ช…ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.)

Lock์€ ๊ณต์œ  ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ์‚ฌ์šฉ๋  ๋•Œ ์ œ์–ดํ•˜๋Š” ๋„๊ตฌ์ด๋‹ค.
์ด๋Š” ๊ณต์œ ๋œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ‘๋…์ ์ ์ธ ์ ‘๊ทผ’์„ ์ œ๊ณตํ•œ๋‹ค.

 

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๊ณต์œ  ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๋…์ ์ ์ธ ์ ‘๊ทผ์„ ์ œ๊ณตํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋™๊ธฐํ™”๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜๋”๋ผ๋„, ํ•ญ์ƒ ์ •์ƒ์ ์œผ๋กœ ์ €์žฅ๋œ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ์›์ž์„ฑ์„ ๋ณด์žฅํ•˜๊ฒŒ ๋œ๋‹ค.

 

๋ณธ ์ฑ…์—์„œ๋Š”, ์ž๋ฐ”๋Š” long, double์„ ์ œ์™ธํ•œ ๋ณ€์ˆ˜๋ฅผ ์ฝ๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ์›์ž์ ์ด๋ผ๊ณ  ํ‘œํ˜„ํ–ˆ๋‹ค. ์™œ์ผ๊นŒ?

์ž๋ฐ”์˜ primitive type์„ ์ƒ๊ฐํ•ด๋ณด์ž.

https://ramj2ee.blogspot.com/2015/09/java-tutorial-java-primitive-data-types.html

JVM์€ ๋ฐ์ดํ„ฐ๋ฅผ 4๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. (=32๋น„ํŠธ๋งŒํผ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.)

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— 32๋น„ํŠธ ์ดํ•˜์ธ boolean, byte, short, char, int, float์˜ ๊ฒฝ์šฐ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ํ•˜๋‚˜์˜ ๋ช…๋ น์–ด๋Š” ์ตœ์†Œ ๋‹จ์œ„์˜ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ž‘์—… ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค ์ˆ˜ ์—†์–ด์„œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•˜๊ฒŒ ๋œ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜, long๊ณผ double์˜ ๊ฒฝ์šฐ 64๋น„ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜๊ฐ€ ์—†์–ด์„œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค.

์ด๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ ‘volatile’์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. (ํ˜น์€ AtomicLong, AtomicDouble ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.) ์šฐ์„  ์ด์— ๋Œ€ํ•ด์„œ๋Š” ๋ฎ์–ด๋‘์ž. (๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!)

 


โœ”๏ธ ๋™๊ธฐํ™”๋ฅผ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ? 

๋จผ์ €, ๋‹จ์ˆœํ•˜๊ฒŒ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์„ ํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฉˆ์ถ˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

ํ˜„์žฌ๋Š” deprecated๋œ Thread.stop()์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜๊ธฐ๋Š” ํ•˜์ง€๋งŒ, ์ด๊ฑด ๋งค์šฐ ์œ„ํ—˜ํ•œ ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„๋“œ๋ฅผ ํ†ตํ•ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

import java.io.IOException;
        import java.util.concurrent.TimeUnit;

public class Main {
    private static boolean isStop = false;
    public static void main(String[] args) throws IOException, InterruptedException {
        Thread thread = new Thread(() -> {
            int count = 0;
            while (!isStop) {
                count++;
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        isStop = true;
    }
}

1์ดˆ ํ›„์— true๋กœ ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด์„œ ์ข…๋ฃŒ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ์ด ์นœ๊ตฌ๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ณ„์† ์‹คํ–‰์ด ๋ ๋ฟ์ด๋‹ค.

 

์ฑ…์—์„œ๋Š” ์•„๋ž˜์˜ ์ฝ”๋“œ๊ฐ€ JVM์ด ํ˜ธ์ด์ŠคํŒ…์„ ํ†ตํ•ด ์ตœ์ ํ™”ํ•œ ์ฝ”๋“œ๋ผ๊ณ  ์†Œ๊ฐœํ–ˆ๋‹ค.

//before
while (!isStop) {
    count++;
}

// after
if (!isStop) {
    while (true) {
        count++;
    }
}

๊ฐœ์ธ์ ์œผ๋กœ, ์™œ ์ด๋ฅผ ํ˜ธ์ด์ŠคํŒ…์ด๋ผ๊ณ  ํ•˜๋Š”์ง€ ์ž˜ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค. ํ˜ธ์ด์ŠคํŒ…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฐœ๋…์ด๋‹ค.

 

๐Ÿ’ฌ ์ด๋ฅผ ์™œ ํ˜ธ์ด์ŠคํŒ…์ด๋ผ๊ณ  ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

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

์ž๋ฐ”์—์„œ ๋ณ€์ˆ˜๋Š” ํ˜ธ์ด์ŠคํŒ…์ด ์•ˆ ๋˜์ง€๋งŒ, ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ์„ ์–ธํ•˜๊ธฐ ์ „์— ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ด์ŠคํŒ…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์ฑ…์—์„œ ์„ค๋ช…ํ•˜๋Š” ํ˜ธ์ด์ŠคํŒ…์€, ๋ฃจํ”„ ๋‚ด์—์„œ ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์—ฐ์‚ฐ๋“ค์€ ๋ฃจํ”„ ๋‚ด๋ถ€๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€์—์„œ ์‹คํ–‰ํ•˜์ž๋Š” ๊ฒƒ์ด๋‹ค.

JIT ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ €๋ ‡๊ฒŒ ๋ฃจํ”„ ๋ฐ–์œผ๋กœ ๊บผ๋‚ธ ๋•๋ถ„์— ๋๋‚˜์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•œ -Djava.compiler๋Š” JVM์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์˜ต์…˜์„ ์„ ํƒํ•œ๋‹ค.

 

java -Djava.compiler=<compiler-name> <class-name>

 

NONE์œผ๋กœ ํ•˜๊ฒŒ ๋˜๋ฉด, JIT ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ฒŒ ๋œ๋‹ค.

 

๐Ÿ’ฌ JIT ์ปดํŒŒ์ผ๋Ÿฌ๋ž€?

์ž๋ฐ”์˜ ์ปดํŒŒ์ผ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

1) ์ž๋ฐ” ์†Œ์Šค์ฝ”๋“œ (.java) ํŒŒ์ผ์„ ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ .class ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผ [์—ฌ๊ธฐ๊นŒ์ง€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์‹คํ–‰]

2) ์ด๋•Œ, ์ด๋Š” ๋ฐ”์ดํŠธ ์ฝ”๋“œ ํ˜•์‹์ด๋ฉฐ ์ปดํŒŒ์ผ๋œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ JVM์˜ ํด๋ž˜์Šค ๋กœ๋”์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค. [๋Ÿฐํƒ€์ž„์— ์‹คํ–‰]

3) ํด๋ž˜์Šค ๋กœ๋”๋Š” ๋‹ค์ด๋‚˜๋ฏน ๋กœ๋”ฉ์„ ํ†ตํ•ด ํ•„์š”ํ•œ ํด๋ž˜์Šค๋“ค์„ ๋กœ๋”ฉ ๋ฐ ๋งํฌํ•˜์—ฌ, JVM์˜ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฐ๋‹ค.

4) JVM ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ์˜จ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋ช…๋ น์–ด ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ์‹คํ–‰๋˜๋Š”๋ฐ, ์ด๋•Œ 2๊ฐ€์ง€์˜ ์‹คํ–‰ ์—”์ง„์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

์ฒซ ๋ฒˆ์งธ๋กœ, ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ํ†ตํ•ด์„œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„์”ฉ ์ฝ๋Š”๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์ผ์ • ํšŸ์ˆ˜ ์ด์ƒ ํ˜ธ์ถœ์ด ๋œ๋‹ค๋ฉด, JIT ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ด๋•Œ ์ตœ์ ํ™”๋œ ๊ธฐ๊ณ„์–ด ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. ํ•œ ์ค„์”ฉ ์ฝ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ์™€ ๋‹ฌ๋ฆฌ, JIT ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜๋‚˜ ํŒŒ์ผ ๋‹จ์œ„๋กœ ์ปดํŒŒ์ผํ•œ๋‹ค. ์ด๋•Œ, ๋ฐ˜๋ณต๋˜๋Š” ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์บ์‹ฑ์„ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์•„๋ฌดํŠผ, JIT ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ ๋ฃจํ”„ ์•ˆ์—์„œ ๋ฐ˜๋ณต๋˜๋Š” ์—ฐ์‚ฐ์€ ๋ฃจํ”„ ๋ฐ–์œผ๋กœ ๊บผ๋‚ด ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. ๋ฃจํ”„ ์•ˆ์—์„œ ์—ฐ์‚ฐ์„ ๋ฐ˜๋ณตํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ์—ฐ์‚ฐ์„ ์žฌ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋น„ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฃจํ”„ ๋ฐ–์—์„œ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•œ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ํ˜ธ์ด์ŠคํŒ…์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

์ฝ”๋“œ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ดํŽด๋ณด์ž.

for (int i = 0; i < 1000000; i++) {
    int a = 10;
    int b = 20;
    int c = a + b;
    result += c;
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ a, b๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ๊ณ„์† ์„ ์–ธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž. ์ด ์ฝ”๋“œ๋ฅผ ํ˜ธ์ด์ŠคํŒ…์„ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

int a = 10;
int b = 20;
for (int i = 0; i < 1000000; i++) {
    int c = a + b;
    result += c;
}

์ด๋ ‡๊ฒŒ ๋ฃจํ”„ ๋‚ด์—์„œ ๊ตณ์ด ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์—ฐ์‚ฐ์— ๋Œ€ํ•ด์„œ ๋ฐ”๊นฅ์œผ๋กœ ๋นผ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค.

 

์šฐ๋ฆฌ๊ฐ€ ์•ž์—์„œ ๋ดค๋˜ ์ฝ”๋“œ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.

while (!isStop) {
    count++;
}

JIT ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ๊ณ„์† isStop ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์ฒดํฌํ•˜๋Š” ๊ฒƒ์„ ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ํŒ๋‹จํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด, ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์ด๋ผ๋ฉด ์ œ์–ด๊ฐ€ ์ € ์ฝ”๋“œ๊นŒ์ง€ ๋‚ด๋ ค์™”์„ ๋•Œ ์™ธ๋ถ€ ์š”์ธ์œผ๋กœ ์ธํ•ด isStop์ด๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋  ์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

if (!isStop) {
    while (true) {
        count++;
    }
}

๊ทธ๋ž˜์„œ JIT ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ๊ฐ’์„ ์ฒดํฌํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ 1๋ฒˆ๋งŒ ์ฒดํฌํ•œ ๋‹ค์Œ์— ํ•˜์œ„์—์„œ while๋ฌธ์œผ๋กœ ๊ณ„์† ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ์—์„œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ isStop์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ true๋กœ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„, ์ด๋ฏธ if๋ฌธ์˜ ์กฐ๊ฑด์€ ๋๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ ธ๋ฒ„๋ฆฌ๊ณ  ๋งˆ๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ์ „๋žต์„ ์ž˜ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค...!

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

 

์ž, ๋‹ค์‹œ ๋Œ์•„๊ฐ€์„œ ์œ„์˜ ๊ทธ๋ฆผ์„ ๋‹ค์‹œ ๋ณด์ž.

ํ•œ ๋ฒˆ ๋” ์ฒจ๋ถ€ํ•จ

JIT ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์„ ๊ป๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์—์„œ๋Š” ๋ฐ”๋กœ ์ข…๋ฃŒ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ทธ๋ƒฅ ๋‹จ์ˆœํžˆ Main.java๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ๋Š” ๊ฐ•์ œ ์ข…๋ฃŒ (^C)๋ฅผ ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

 

๊ทธ๋ ‡๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ• ๊นŒ?

import java.io.IOException;
        import java.util.concurrent.TimeUnit;

public class Main {
    private static boolean isStop = false;

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

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

    public static void main(String[] args) throws IOException, InterruptedException {
        Thread thread = new Thread(() -> {
            int count = 0;
            while (!isStop()) {
                count++;
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        requestStop();
    }
}

 

synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค.

ํ˜„์žฌ isStop์˜ ํ•„๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฉ”์„œ๋“œ (requestStop)์™€ ํ•„๋“œ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๋ฉ”์„œ๋“œ (isStop) ๋ชจ๋‘๋ฅผ ๋™๊ธฐํ™”ํ•˜์˜€๋‹ค.

ํ”ํžˆ๋“ค ์“ฐ๊ธฐ ๋™๊ธฐํ™”๋งŒ ์ง„ํ–‰ํ•˜๋ฉด ๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ƒ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ๋™๊ธฐํ™”๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค. (๋ผ๊ณ  ์ฑ…์—์„œ ๋งํ–ˆ๋‹ค.)

 

๐Ÿค” ๊ทธ๋Ÿฐ๋ฐ, ์‹ค์ œ๋กœ ์‹คํ—˜ํ•ด๋ณด์•˜์„ ๋•Œ ์“ฐ๊ธฐ ๋™๊ธฐํ™”๋งŒ ํ–ˆ์„ ๊ฒฝ์šฐ๋Š” ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜์ง€ ์•Š์•˜์ง€๋งŒ, ์ฝ๊ธฐ ๋™๊ธฐํ™”๋งŒ ํ–ˆ์„ ๋•Œ๋Š” ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜์—ˆ๋‹ค. ์ด์œ ์— ๋Œ€ํ•ด์„œ ์ƒ๊ฐํ•ด๋ณด์•˜๋‹ค. ์•„๋ž˜๋Š” ํ•„์ž์˜ ์ƒ๊ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฝ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

์ฝ๊ธฐ๋งŒ ๋™๊ธฐํ™”๋ฅผ ํ–ˆ์„ ๊ฒฝ์šฐ ๋ณ€์ˆ˜๋ฅผ ์ฝ๋Š” ๋„์ค‘์—๋Š” ๋ฝ์„ ๊ฑธ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, Main ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ๋’ค, ํ•ด๋‹น ๊ฐ’์ด true์ธ ์ƒํƒœ๋กœ ๊ณ„์† ๋ฐ›์•„์˜ฌ ์ˆ˜๋ฐ–์— ์—†์œผ๋‹ˆ๊นŒ (์™ธ๋ถ€์—์„œ ๋ณ€๊ฒฝํ•  ์ˆ˜๊ฐ€ ์—†์Œ) ์ข…๋ฃŒ๋˜๋Š” ๊ฒŒ ์•„๋‹๊นŒ ์‹ถ๋‹ค. (=ํ•ญ์ƒ ์ตœ์‹ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค)

๋ฐ˜๋ฉด์— ์“ฐ๊ธฐ๋งŒ ๋™๊ธฐํ™”๋ฅผ ํ–ˆ๋‹ค๋ฉด, Main ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒํ•˜๊ธฐ ์ „์— ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ๊นŒ์ง€๋Š” ์›์ž์ ์ด์ง€๋งŒ, ๊ฐ’์„ ์ฝ์–ด์˜ค๋Š” ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์ด ์—†์ด ๊ทธ๋ƒฅ ์‹คํ–‰๋œ๋‹ค. ์ด๋Ÿฌ๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” Main ์Šค๋ ˆ๋“œ์™€, isStop()์„ ํ˜ธ์ถœํ•˜๋Š” ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์ด์˜ ์ผ๊ด€์„ฑ์ด ๋งž์ง€ ์•Š๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค. ์ผ๊ด€์„ฑ์ด ๊นจ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋Œ€๋กœ ๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ์ฝ์–ด์˜ค์ง€ ๋ชปํ•˜๊ณ  ์–ด๋– ํ•œ ์“ฐ๋ ˆ๊ธฐ๊ฐ’์„ ์ฝ์–ด์˜ค๋ฉด์„œ ์ข…๋ฃŒ๊ฐ€ ์•ˆ ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ... ๋ผ๋Š” ๊ฒŒ ๋‚˜์˜ ์ƒ๊ฐ์ด๋‹ค.

์–ด๋– ํ•œ ์ด์œ ๋“ , ๋‘ ๋ฉ”์„œ๋“œ ๋ชจ๋‘์— synchronized ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์•ผ ๋”์šฑ ์•ˆ์ „ํ•˜๊ฒŒ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์€ ํ™•์‹คํ•˜๋‹ค.

์›ฌ๋งŒํ•˜๋ฉด ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ๋ชจ๋‘ ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์„œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•˜๋„๋ก ํ•˜์ž.

 


๐Ÿ’ฌ  synchronized ํ‚ค์›Œ๋“œ์˜ ์›๋ฆฌ

์šฐ์„ , ์ž๋ฐ”์—์„œ ๋ชจ๋“  ๊ฐ์ฒด๋“ค์€ ‘Monitor’๋ผ๋Š” ๊ฒƒ์„ ๊ฐ€์ง€๋ฉฐ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด๋กœ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๊ฒŒ ํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด, ๊ฐ์ฒด๋Š” Heap ์˜์—ญ์— ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์—ฌ๊ธฐ์„œ monitor๋ž€, ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ• ์ค‘ 'critical section (์ž„๊ณ„ ์˜์—ญ)'์— ๋Œ€ํ•ด ๋™๊ธฐํ™”๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ผ์ข…์˜ ๋งค์ปค๋‹ˆ์ฆ˜์ด๋‹ค. ์ž„๊ณ„ ์˜์—ญ์€ ๊ณต์œ ๋œ ์ž์›์— ๋Œ€ํ•ด์„œ ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ์ด๋•Œ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค. (๋‹ค์ค‘ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ์Šค๋ ˆ๋“œ๋Š” X)

 

Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor. A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.

๊ทธ๋ฆฌ๊ณ , synchronized๋Š” ์ด๋Ÿฌํ•œ critical section์— ๋Œ€ํ•ด์„œ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค! 

synchronized๋ฅผ ํ†ตํ•ด ์ž„๊ณ„ ์˜์—ญ์— ๋Œ€ํ•ด ์„ ์–ธ์„ ํ•ด์ฃผ๊ณ , ํ•ด๋‹น ์ž„๊ณ„ ์˜์—ญ์— ๋Œ€ํ•ด ๋ชจ๋‹ˆํ„ฐ ๋ฝ์„ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ,

์ด๋ ‡๊ฒŒ ์–ป์€ ๋ชจ๋‹ˆํ„ฐ ๋ฝ์€ ํ•ด๋‹น ์ž„๊ณ„ ์˜์—ญ์„ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๊ฒŒ ๋œ๋‹ค!

 

monitor๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์„ monitorenter, ๋†“๋Š” ๊ฒƒ์„ monitorexit์ด๋ผ๊ณ  ํ•œ๋‹ค.

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

 

1. synchronized ๋ธ”๋ก์ด ์‹œ์ž‘๋˜๋ฉด, JVM์€ ํ•ด๋‹น ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ฝ์„ ํš๋“ํ•œ๋‹ค. (monitorenter)
2. synchronized ๋ธ”๋ก์—์„œ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ๋Š”, ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ฝ์„ ๊ฐ€์ง€๊ณ  ์‹คํ–‰๋œ๋‹ค.
3. ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ฝ์„ ํš๋“ํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์„ ํš๋“ํ•˜๊ธฐ ์ „๊นŒ์ง€ block ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค.
4. synchronized ๋ธ”๋ก์ด ์‹คํ–‰ ์™„๋ฃŒ๋˜๋ฉด, JVM์€ ํ•ด๋‹น ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ฝ์„ ํ•ด์ œํ•œ๋‹ค. (monitorexit)

 

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฝ์„ ํ™œ์šฉํ•˜์—ฌ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค!


 

์•„์ง ๊ฐœ๋…์ด ์™„๋ฒฝํ•˜๊ฒŒ ์Šต๋“๋œ ๋Š๋‚Œ์€ ์•„๋‹ˆ์ง€๋งŒ... ์ถ”๊ฐ€์ ์œผ๋กœ ๊ด€๋ จํ•ด์„œ ๋˜ ๊ธ€์„ ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค...! ๐Ÿ™‡‍โ™€๏ธ

Comments