Claire's Study Note

[ํ—ค๋“œํผ์ŠคํŠธ ๋””์ž์ธ ํŒจํ„ด] 05. ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด

by Hi.Claire
๋ฐ˜์‘ํ˜•

๐Ÿ“š ํ—ค๋“œํผ์ŠคํŠธ ๋””์ž์ธ ํŒจํ„ด (์—๋ฆญ ํ”„๋ฆฌ๋จผ ์™ธ, ํ•œ๋น›๋ฏธ๋””์–ด)

 

1. ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์˜ ์ •์˜

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด(Singleton Pattern)

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด(Singleton Pattern)์€ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹จ ํ•˜๋‚˜๋งŒ ๋งŒ๋“ค๊ณ , ๊ทธ ์ธ์Šคํ„ด์Šค๋กœ์˜ ์ „์—ญ ์ ‘๊ทผ์„ ์ œ๊ณตํ•œ๋‹ค.

 

์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์ด ํ•„์š”ํ•œ ์˜ˆ

์Šค๋ ˆ๋“œ ํ’€(Thread pool), ์บ์‹œ(Cache), ๋Œ€ํ™”์ƒ์ž, ์‚ฌ์šฉ์ž ์„ค์ •, ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์„ค์ •์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒด, ๋กœ๊ทธ ๊ธฐ๋ก์šฉ ๊ฐ์ฒด, ๋””๋ฐ”์ด์Šค ๋“œ๋ผ์ด๋ฒ„ ๋“ฑ์˜ ๊ฐ์ฒด๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์–ด๋„ ์ž˜ ๋Œ์•„๊ฐ„๋‹ค.

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

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.

์ „์—ญ๋ณ€์ˆ˜์— ๊ฐ์ฒด๋ฅผ ๋Œ€์ž…ํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋  ๋•Œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

๋งŒ์•ฝ ๊ทธ ๊ฐ์ฒด๊ฐ€ ์ž์›์„ ๋งŽ์ด ์ฐจ์ง€ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ทธ ๊ฐ์ฒด๋ฅผ ํ•œ ๋ฒˆ๋„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ดœํžˆ ์ž์›๋งŒ ์žก์•„๋จน๋Š” ์“ธ๋ฐ์—†๋Š” ๊ฐ์ฒด๊ฐ€ ๋˜๊ณ  ๋ง ๊ฒƒ์ด๋‹ค.

๋ฐ˜๋ฉด ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•„์š”ํ•  ๋•Œ๋งŒ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

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

 

2. ๊ณ ์ „์ ์ธ ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด ๊ตฌํ˜„๋ฒ•

public class Singleton {
    // Singleton ํด๋ž˜์Šค์˜ ํ•˜๋‚˜๋ฟ์ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ €์žฅํ•˜๋Š” static ๋ณ€์ˆ˜
    private static Singleton uniqueInstance;

    // private ์ƒ์„ฑ์ž๋กœ ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ์˜ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋ง‰๋Š”๋‹ค.
    private Singleton() {}     

    // Singleton ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฆฌํ„ดํ•˜๋Š” static ๋ฉ”์„œ๋“œ
    public static Singleton getInstance() {
        // ์•„์ง ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์•˜๋‹ค๋ฉด, private์œผ๋กœ ์„ ์–ธ๋œ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ Singleton ๊ฐ์ฒด๋ฅผ ๋งŒ๋“  ๋‹ค์Œ uniqueInstance์— ๊ทธ ๊ฐ์ฒด๋ฅผ ๋Œ€์ž…ํ•œ๋‹ค.
        // ์ด๋Ÿฌ๋ฉด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด ์˜ค๊ธฐ ์ „๊นŒ์ง€๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์„ '๊ฒŒ์œผ๋ฅธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ(lazy instantiation)'์ด๋ผ ํ•œ๋‹ค.
        if(uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }         

        return uniqueIntance;   
    } 
}

ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜์—ฌ ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ์˜ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋ง‰๋Š”๋‹ค.

static ๋ฉ”์„œ๋“œ์ธ getInstance()๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ด๋•Œ ์ด๋ฏธ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

3. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋ฌธ์ œ ์‚ดํŽด๋ณด๊ธฐ

์œ„์™€ ๊ฐ™์€ ๊ณ ์ „์ ์ธ ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„์ง ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์‹œ์— getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ ์Šค๋ ˆ๋“œ์— ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด๋‹ค.

 

4. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ

๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ์‹ฑ๊ธ€ํ„ด์ด ๋Œ์•„๊ฐ€๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์„ธ ๊ฐ€์ง€๋ฅผ ์‚ดํŽด๋ณด์ž.

 

๋ฐฉ๋ฒ• 1. getInstance() ๋ฉ”์„œ๋“œ ๋™๊ธฐํ™”ํ•˜๊ธฐ

public class Singleton {

    private static Singleton uniqueInstance;

    private Singleton() {}

    // getInstance() ๋ฉ”์„œ๋“œ์— synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์„ ๋๋‚ด๊ธฐ ์ „๊นŒ์ง€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค.
    // ์ฆ‰, 2๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” ์ผ์€ ์ผ์–ด๋‚˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
    public static synchronized Singleton getInstance() {

        if(uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }

        return uniqueInstance;
    }
}

 

getInstance() ๋ฉ”์„œ๋“œ์— synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฉ”์„œ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์„ ๋๋‚ด๊ธฐ ์ „๊นŒ์ง€๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฉ”์„œ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋ฉด ์†๋„ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋ฉด ์„ฑ๋Šฅ์ด 100๋ฐฐ ์ •๋„ ์ €ํ•˜๋œ๋‹ค.

๋งŒ์•ฝ getInstance() ๋ฉ”์„œ๋“œ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ณ‘๋ชฉ์œผ๋กœ ์ž‘์šฉํ•œ๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด๋ด์•ผ ํ•œ๋‹ค.

๋˜ ์กฐ๊ธˆ ๋” ์ƒ๊ฐํ•ด๋ณด๋ฉด, ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์€ ์ด ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹œ์ž‘๋  ๋•Œ๋ฟ์ด๋ผ๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

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

 

๋ฐฉ๋ฒ• 2. ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์ƒ์„ฑํ•˜์ง€ ๋ง๊ณ  ์ฒ˜์Œ๋ถ€ํ„ฐ ์ƒ์„ฑํ•˜๊ธฐ

public class Singleton {

    // ์ •์  ์ดˆ๊ธฐํ™” ๋ถ€๋ถ„(static initializer)์—์„œ Singleton์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {

        // ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฆฌํ„ด๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.
        return uniqueInstance;
    }
}

 

์œ„ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ JVM์—์„œ Singleton์˜ ํ•˜๋‚˜๋ฟ์ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

JVM์—์„œ ํ•˜๋‚˜๋ฟ์ธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์ „๊นŒ์ง€ ๊ทธ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋„ uniqueInstance ์ •์  ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ๊ฒŒ์œผ๋ฅธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ํ•  ์ˆ˜ ์—†๊ณ , ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

 

๋ฐฉ๋ฒ• 3. DCL(Double-Checked Locking)์„ ์จ์„œ getInstance() ๋ฉ”์„œ๋“œ์—์„œ ๋™๊ธฐํ™”๋˜๋Š” ๋ถ€๋ถ„ ์ค„์ด๊ธฐ

public class Singleton {

    // ์ •์  ๋ณ€์ˆ˜์— volatile ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ์“ฐ๋”๋ผ๋„ uniqueInstance ๋ณ€์ˆ˜๊ฐ€ Singleton ์ธ์Šคํ„ด์Šค๋กœ ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ณผ์ •์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง„ํ–‰๋œ๋‹ค.
    private volatile static Singleton uniqueInstance;

    private Singleton() {}

    public static Singleton getInstance() {

        // ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์—†์œผ๋ฉด ๋™๊ธฐํ™”๋œ ๋ธ”๋ก์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค.
        if(uniqueInstance == null) {

            // ์ฒ˜์Œ์—๋งŒ ๋™๊ธฐํ™”๋œ๋‹ค.
            synchronized (Singleton.class) {

                // ๋ธ”๋ก ๋‚ด์—์„œ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์—†์„ ๋•Œ์—๋งŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
                if(uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }

        return uniqueInstance;
    }
}

 

DCL(Double-Checked Locking)์„ ์‚ฌ์šฉํ•˜๋ฉด ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ, ์ƒ์„ฑ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๋•Œ์—๋งŒ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌ๋ฉด ์ฒ˜์Œ์—๋งŒ ๋™๊ธฐํ™”ํ•˜๊ณ  ๋‚˜์ค‘์—๋Š” ๋™๊ธฐํ™”ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

๋‹จ, DCL์€ ์ž๋ฐ” 1.4 ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ์“ธ ์ˆ˜ ์—†๋‹ค.

์ž๋ฐ” 1.4๋ณด๋‹ค ๋‚ฎ์€ ๋ฒ„์ „์˜ JVM ์ค‘์—๋Š” volatile ํ‚ค์›Œ๋“œ๋ฅผ ์จ๋„ DCL์—์„œ ๋™๊ธฐํ™”๊ฐ€ ์ œ๋Œ€๋กœ ์•ˆ ๋˜๋Š” ์ผ์ด ๋งŽ๋‹ค.

 

5. ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์˜ ๋‹ค๋ฅธ ๋ฌธ์ œ ์‚ดํŽด๋ณด๊ธฐ

1. ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ 2๊ฐœ ์ด์ƒ์ผ ๋•Œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ

ํด๋ž˜์Šค ๋กœ๋”๋งˆ๋‹ค ์„œ๋กœ ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ(๊ฐ ํด๋ž˜์Šค ๋กœ๋”๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ) ๋กœ๋”ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ด๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ„ด์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๋•Œ์—๋Š” ์‹ฑ๊ธ€ํ„ด์„ ์กฐ์‹ฌํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

ํด๋ž˜์Šค ๋กœ๋”๋ฅผ ์ง์ ‘ ์ง€์ •ํ•œ๋‹ค๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜๋Š” ์žˆ๋‹ค.

 

2. ๋ฆฌํ”Œ๋ ‰์…˜, ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™” ๋ฌธ์ œ

๋ฆฌํ”Œ๋ ‰์…˜, ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”๋„ ์‹ฑ๊ธ€ํ„ด์—์„œ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.

TODO ๋ฆฌํ”Œ๋ ‰์…˜, ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™” ๊ณต๋ถ€ํ•˜๊ธฐ

 

3. ๋А์Šจํ•œ ๊ฒฐํ•ฉ ์›์น™์˜ ์œ„๋ฐฐ

๋А์Šจํ•œ ๊ฒฐํ•ฉ ์›์น™์— ๋”ฐ๋ฅด๋ฉด "์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊ฐ์ฒด ์‚ฌ์ด์—์„œ ์ตœ๋Œ€ํ•œ ๋А์Šจํ•œ ๊ฒฐํ•ฉ์„ ์ถ”๊ตฌ"ํ•ด์•ผ ํ•œ๋‹ค.

์‹ฑ๊ธ€ํ„ด์— ์˜์กดํ•˜๋Š” ๊ฐ์ฒด๋Š” ์ „๋ถ€ ํ•˜๋‚˜์˜ ๊ฐ์ฒด์— ๋‹จ๋‹จํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ„ด์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์ด๋Ÿฐ ์›์น™์„ ์œ„๋ฐฐํ•˜๊ธฐ ์‰ฝ๋‹ค.

์‹ฑ๊ธ€ํ„ด์„ ๋ฐ”๊พธ๋ฉด ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ฐ์ฒด๋„ ๋ฐ”๊ฟ”์•ผ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

4. ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ

์‹ฑ๊ธ€ํ„ด์˜ ์„œ๋ธŒ ํด๋ž˜์Šค(์ž์‹ ํด๋ž˜์Šค)๋ฅผ ๋งŒ๋“ค ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๋งˆ์ฃผ์น˜๋Š” ๊ฑธ๋ฆผ๋Œ์ด ๋ฐ”๋กœ ์ƒ์„ฑ์ž๊ฐ€ private์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

private์œผ๋กœ ์ง€์ •๋œ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋Š” ํ™•์žฅํ•  ์ˆ˜ ์—†๊ธฐ์— ์ƒ์„ฑ์ž๋ฅผ public ๋˜๋Š” protected๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฏ€๋กœ ๋”๋Š” ์‹ฑ๊ธ€ํ„ด์ด ์•„๋‹ˆ๊ฒŒ ๋œ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ์‹ฑ๊ธ€ํ„ด์€ ์ •์  ๋ณ€์ˆ˜๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ๋ชจ๋“  ์„œ๋ธŒํด๋ž˜์Šค๊ฐ€ ๋˜‘๊ฐ™์€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ์ ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋ฒ ์ด์Šค ํด๋ž˜์Šค์—์„œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ™์€ ๊ฑธ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

 

6. ์‹ฑ๊ธ€ํ„ด ํŒจํ„ด์˜ ๋‹ค๋ฅธ ๋ฌธ์ œ ํ•ด๊ฒฐํ•˜๊ธฐ

๋ฐฉ๋ฒ• 1. Enum ์‚ฌ์šฉํ•˜๊ธฐ

์ง€๊ธˆ๊นŒ์ง€ ๋…ผ์˜ํ•œ ๋™๊ธฐํ™” ๋ฌธ์ œ, ํด๋ž˜์Šค ๋กœ๋”ฉ ๋ฌธ์ œ, ๋ฆฌํ”Œ๋ ‰์…˜, ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™” ๋ฌธ์ œ ๋“ฑ์€ enum์œผ๋กœ ์‹ฑ๊ธ€ํ„ด์„ ์ƒ์„ฑํ•จ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

public enum Singleton {
    UNIQUE_INSTANCE;
}

public class SingletonClient {
    public static void main(String[] args) {

        Singleton singleton = Singleton.UNIQUE_INSTANCE;

        // ์—ฌ๊ธฐ์„œ ์‹ฑ๊ธ€ํ„ด ์‚ฌ์šฉ
    }
}

 

์ด ๋ฐฉ๋ฒ•์€ Eager Initialization์œผ๋กœ ์ธํ•œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‹ฑ๊ธ€ํ„ด์ด enum ์™ธ์˜ ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

 

๋ฐฉ๋ฒ• 2. Lazy Holder ์‚ฌ์šฉํ•˜๊ธฐ

public class Singleton {

    private Singleton() {}

    // private static inner class
    private static inner class LazyHolder {

        // Lazy Holder ํด๋ž˜์Šค ์ดˆ๊ธฐํ™” ๊ณผ์ •์—์„œ JVM์ด Tread-Safeํ•˜๊ฒŒ instance๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
        private static final Singleton uniqueInstance = new Singleton();
    }

    public static Singleton getInstance() {

        // LazyHolder์˜ uniqueInstance์— ์ ‘๊ทผํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
        return LazyHolder.uniqueInstance;
    }
}

 

์ด ๋ฐฉ์‹์€ Eager Initialization์„ ๊ฐœ์„ ํ•œ ๋ฐฉ์‹์ด๋‹ค.

์‹ฑ๊ธ€ํ„ด์˜ getInstance() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด LazyHolder์˜ uniqueInstance ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋Š”๋ฐ, ์ด๋•Œ LazyHolder๊ฐ€ static inner class์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค์˜ ์ดˆ๊ธฐํ™” ๊ณผ์ •์ด ์ด๋ฃจ์–ด์ง€๋ฉด์„œ uniqueInstance ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

JVM์€ ํด๋ž˜์Šค์˜ ์ดˆ๊ธฐํ™” ๊ณผ์ •์—์„œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

์ฆ‰, uniqueInstance๋Š” getInstance() ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ LazyHolder ํด๋ž˜์Šค์˜ ์ดˆ๊ธฐํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๋ฉด์„œ JVM์— ์˜ํ•ด ์›์ž์„ฑ์ด ๋ณด์žฅ๋œ ์ƒํƒœ๋กœ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ๋˜๊ณ , final ๋ณ€์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ดํ›„๋กœ ๋‹ค์‹œ uniqueInstance์— ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ํ• ๋‹น๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

getInstance() ๋ฉ”์„œ๋“œ์— synchronized๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ JVM์— ์˜ํ•ด ์›์ž์„ฑ์ด ๋ณด์žฅ๋˜๋ฏ€๋กœ ์ด๋Ÿฌํ•œ JVM์˜ ํŠน์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ๋ง‰๋Š” ๋ฐฉ์‹์ด๋‹ค.

์—ญ์ง๋ ฌํ™” ์ˆ˜ํ–‰ ์‹œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , ๋ฆฌํ”Œ๋ ‰์…˜์„ ์ด์šฉํ•ด ๋‚ด๋ถ€ ์ƒ์„ฑ์ž ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ •๋ฆฌํ•˜์ž๋ฉด, ์ง๋ ฌํ™” ๋“ฑ ์•ˆ์ •์„ฑ์ด ์ค‘์š”์‹œ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” enum์„, ์„ฑ๋Šฅ์ด ์ค‘์š”์‹œ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” Lazy Holder๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

(์ฐธ๊ณ ) https://github.com/IT-Book-Organization/HeadFirst-DesignPattern/tree/main/Chapter_05

 

๋ฐ˜์‘ํ˜•

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Claire's Study Note

Hi.Claire

ํ™œ๋™ํ•˜๊ธฐ