Skip to main content

Singleton

About 2 minJavaSingletongitgithubjavakotlinandroid

Singleton ๊ด€๋ จ


Singleton ์€ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ œํ•œ์‹œํ‚ค๋Š” ๋ชฉ์ ์™ธ์—๋„ ์ง€์—ฐ ์ดˆ๊ธฐํ™”(lazy initializaion) ๋ชฉ์ ๋„ ์žˆ๋‹ค.

๊ธฐ๋ณธ ์ฝ”๋“œ

public class Singleton { 
     private static Singleton instance;      
     private Singleton() {} 
     public static Singleton getInstance() { 
          if (instance == null) 
               instance = new Singleton(); 
          return instance; 
     } 
}

private ์ƒ์„ฑ์ž๋กœ ์™ธ๋ถ€์—์„œ Singleton ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๊ณ  getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ œ๊ณตํ•œ๋‹ค. getInstance() ์—์„œ๋Š” instance ๊ฐ€ null ์ผ๋•Œ๋งŒ ์ƒ์„ฑํ•˜๋„๋ก ํ•ด ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ œํ•œ์‹œํ‚จ๋‹ค.

ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์œผ๋กœ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋Œ๋ฆฌ๊ฒŒ ๋˜๋ฉด race condition ๋•Œ๋ฌธ์— ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. ์Šค๋ ˆ๋“œ A์™€ ์Šค๋ ˆ๋“œ B๊ฐ€ ๋™์‹œ์— getInstance()๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ์น˜์ž. instance ๋ณ€์ˆ˜๊ฐ€ null์ด๋ผ๋Š” ์‚ฌ์‹ค์„ ๋ณธ ๋‹ค์Œ ์Šค๋ ˆ๋“œ A๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ๋‹ค. ์Šค๋ ˆ๋“œ B๋„ instance ๋ณ€์ˆ˜๊ฐ€ null์ธ์ง€ ์‚ดํŽด๋ณธ๋‹ค. ์ด๋•Œ instance ๋ณ€์ˆ˜์˜ null ์—ฌ๋ถ€๋Š” ์Šค์ผ€์ค„์ด ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋ ์ง€ ๋˜๋Š” ์Šค๋ ˆ๋“œ A๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  instance ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๊ธฐ๊นŒ์ง€ ์–ผ๋งˆ๋‚˜ ๊ฑธ๋ฆฌ๋Š”์ง€ ๋“ฑ์˜ ์˜ˆ์ธกํ•˜๊ธฐ ์–ด๋ ค์šด ํƒ€์ด๋ฐ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค. ์›๋ž˜ getInstance()๋Š” ํ•ญ์ƒ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ์„ค๊ณ„๋ผ ์žˆ๋Š”๋ฐ, ์Šค๋ ˆ๋“œ B๊ฐ€ ์‚ดํŽด๋ณด๋Š” ๊ทธ ์‹œ์ ์— instance ๋ณ€์ˆ˜๊ฐ€ null์ด๋ฉด getInstance()๋ฅผ ํ˜ธ์ถœํ•œ ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ์ž ์„œ๋กœ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜๋„ ์žˆ๋‹ค.


๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋˜๊ฒŒ ํ•˜๋ ค๋ฉด?

๋ฐฉ๋ฒ•1 synchronized ๋‹จ์ˆœ์ถ”๊ฐ€

public class Singleton { 
     private static Singleton instance; 
     private Singleton() {} 
     public static synchronized Singleton getInstance() { 
          if (instance == null) 
               instance = new Singleton(); 
          return instance; 
     } 
}

๊ฐ€์žฅ ์‰ฝ๊ฒŒ ์ƒ๊ฐ๋‚˜๋Š”๊ฑด getInstance ๋ฉ”์„œ๋“œ์— synchronized ๋ฅผ ๋ถ™์ด๋Š” ๊ฑฐ๋‹ค. ํ•˜์ง€๋งŒ race condition ์€ ํ”ผํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ๋ถ€์ •์ ์ธ ์ž„ํŒฉํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. getInstance ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋ชจ๋“  ํ˜ธ์ถœ์€ ๋™๊ธฐํ™” ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๊ฐ–๊ฒŒ ๋๋‹ค. ์‚ฌ์‹ค race condition ๊ฐ€๋Šฅ์„ฑ์€ ๋‹จ์ง€ instance ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์ฒ˜์Œ ํ• ๋‹น๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•  ๋นˆ๋„๊ฐ€ ๋งค์šฐ ๋‚ฎ๋‹ค. ๋”ฐ๋ผ์„œ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•์ด ์˜คํžˆ๋ ค ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํฐ ๋ฐฉ๋ฒ•์ด๋‹ค.

๋ฐฉ๋ฒ•2 ์„ฑ์งˆ ๊ธ‰ํ•œ ์ดˆ๊ธฐํ™”

์„ฑ์งˆ ๊ธ‰ํ•œ ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ•์€ static ๊ตฌ๋ฌธ์—์„œ ์ดˆ๊ธฐํ™”ํ•จ์œผ๋กœ์จ ์ƒ์„ฑ๋  ๋•Œ๋‚˜ ์ฐธ์กฐ๋  ๋•Œ ๋”ฐ๋กœ ๋™๊ธฐํ™”๋ฅผ ๋งž์ถœ ํ•„์š”์—†๊ฒŒ ํ•œ๋‹ค.

static ์œผ๋กœ ์„ ์–ธ๋œ ์ดˆ๊ธฐํ™” ๋ฌธ์žฅ์€ JVM ์—์„œ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด๋“ค์ด๊ณ  ์‹ค์ œ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์‹คํ–‰๋œ๋‹ค. ์ด๋Ÿฐ ์ดˆ๊ธฐํ™” ๊ณผ์ •์—์„œ JVM์ด ๋ฝ์„ ํ™•๋ณดํ•˜๋ฉฐ ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์ฝํ˜€์ ธ ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฝ์„ ๋‹ค์‹œ ํ™•๋ณดํ•˜๊ฒŒ ๋ผ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ JVM์ด ๋ฝ์„ ํ™•๋ณดํ•œ ์ƒํƒœ์—์„œ ๋ฉ”๋ชจ๋ฆฌ์— ์“ฐ์—ฌ์ง„ ๋‚ด์šฉ์€ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

// ์ž๋ฐ” ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ p501
public class Singleton { 
     private static Singleton instance = new Singleton(); 
     public static Singleton getInstance() { 
          return instance; 
     } 
}

๋‹จ ์ด ๋ฐฉ๋ฒ•์€ ์ดˆ๊ธฐํ™”ํ•œ ๊ฐ์ฒด์˜ ๋‚ด์šฉ์ด ๊ทธ๋Œ€๋กœ์ธ ์ƒํƒœ๋ฅผ ๊ฐ€์ •ํ•  ๋•Œ๋งŒ ์„ฑ๋ฆฝํ•œ๋‹ค.

๋ฐฉ๋ฒ•3 ๋Šฆ์€ ์ดˆ๊ธฐํ™” ํ™€๋” ํด๋ž˜์Šค

// ์ž๋ฐ” ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ p502
public class ResourceFactory { 
     private static class ResourceHolder { 
          public static Resource resource = new Resource(); 
     } 
     public static Resource getResource() { 
          return ResourceHolder.resource; 
     } 
}

์˜ค๋กœ์ง€ Resource ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋ชฉ์ ์œผ๋กœ ๋Šฆ์€ ์ดˆ๊ธฐํ™” ํ™€๋” ํด๋ž˜์Šค ๊ตฌ๋ฌธ์„ ์ ์šฉํ•ด ์ž‘์„ฑํ•œ ํด๋ž˜์Šค๋‹ค. JVM์€ ResourceHolder ํด๋ž˜์Šค๋ฅผ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, Resource ํด๋ž˜์Šค ์—ญ์‹œ static ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์—์„œ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์„ ์ ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์–ด๋Š ์Šค๋ ˆ๋“œ๊ฑด ๊ฐ„์— ์ฒ˜์Œ getResource() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด JVM์—์„œ ResourceHolder ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด๋“ค์—ฌ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ResourceHolder ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋„์ค‘์— Resource ํด๋ž˜์Šค ์—ญ์‹œ ์ดˆ๊ธฐํ™”ํ•˜๊ฒŒ ๋ผ ์žˆ๋‹ค.

(์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” item83) '์ง€์—ฐ ์ดˆ๊ธฐํ™”๋Š” ์‹ ์ค‘ํžˆ ์‚ฌ์šฉํ•˜๋ผ' ์—์„œ๋„ ์œ„์˜ ๋ฐฉ์‹์„ ์ถ”์ฒœํ•œ๋‹ค. '์„ฑ๋Šฅ ๋ฌธ์ œ ๋•Œ๋ฌธ์— ์ •์  ํ•„๋“œ ์ดˆ๊ธฐํ™”๋ฅผ ์ง€์—ฐ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ๋Š” ์ดˆ๊ธฐํ™” ์ง€์—ฐ ๋‹ด๋‹น ํด๋ž˜์Šค(lazy initialization holder class) ์ˆ™์–ด๋ฅผ ์ ์šฉํ•˜๋ผ' ๋ผ๊ณ  ๋˜์–ด์žˆ๋‹ค.

// ์ดํŽ™ํ‹ฐ๋ธŒ์ž๋ฐ” ์•„์ดํ…œ83
private static class FieldHolder {
	static final FieldType field = computeFieldValue();
}

private static FieldType getField() { return FieldHolder.field; }

์ด ์ˆ™์–ด๊ฐ€ ์ข‹์€ ์ ์€ getField ๋ฅผ ๋™๊ธฐํ™” ๋ฉ”์„œ๋“œ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ดˆ๊ธฐํ™”๋ฅผ ์ง€์—ฐ์‹œ์ผœ๋„ ๋ฉ”์„œ๋“œ ์ด์šฉ ๋น„์šฉ์€ ์ „ํ˜€ ์ฆ๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ตœ์‹  VM์€ ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ ์ ‘๊ทผ์€ ๋™๊ธฐํ™”ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํด๋ž˜์Šค๊ฐ€ ์ผ๋‹จ ์ดˆ๊ธฐํ™”๋˜๊ณ  ๋‚˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋ฐ”๊ฟ”์„œ ์•ž์œผ๋กœ์˜ ํ•„๋“œ ์ ‘๊ทผ์—๋Š” ์–ด๋–ค ๋™๊ธฐํ™”๋‚˜ ๊ฒ€์‚ฌ๋„ ํ•„์š”์น˜ ์•Š๋„๋ก ๋งŒ๋“ ๋‹ค.

๋ฐฉ๋ฒ•4 Supplier ์‚ฌ์šฉ

์ž๋ฐ”8์—์„œ ์ถ”๊ฐ€๋œ FunctionalInterface Supplier<T> ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

// Functional Programming in Java8
public class Holder {
  private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
  
  public Holder() {
    System.out.println("Holder created");
  }

  public Heavy getHeavy() {
    return heavy.get();
  }
  //...

  private synchronized Heavy createAndCacheHeavy() {
    class HeavyFactory implements Supplier<Heavy> {
      private final Heavy heavyInstance = new Heavy();

      public Heavy get() { return heavyInstance; }
    }

    if(!HeavyFactory.class.isInstance(heavy)) {
      heavy = new HeavyFactory();
    }
    
    return heavy.get();
  }
}
final Holder holder = new Holder();
holder.getHeavy();

Holder์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ Heavy์˜ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฒ˜์Œ holder.getHeavy() ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ๊ทธ ์•ˆ์— heavy๋Š” ๊ธฐ๋ณธ Supplier<Heavy> type ์ด๊ธฐ ๋•Œ๋ฌธ์— Supplier ๊ตฌํ˜„์ฒด๊ฐ€ ์‹คํ–‰๋œ๋‹ค. ๋”ฐ๋ผ์„œ createAndCacheHeavy() ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ , heavy ๋Š” HeavyFactory๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ์ƒˆ๋กญ๊ฒŒ HeavyFactory ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ฆฌ๊ณ  HeavyFactory ์—์„œ Heavy ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  get() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ œ๊ณตํ•œ๋‹ค.

๊ทธ ์ดํ›„๋ถ€ํ„ฐ๋Š” heavy ๊ฐ€ HeavyFactory ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— getHeavy() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๋ฐ”๋กœ heavyInstace() ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค. ์ฒ˜์Œ ๊ฐ์ฒด ์ƒ์„ฑํ•  ๋•Œ๋งŒ synchronized ๋ถ€๋ถ„์œผ๋กœ ๋ณดํ˜ธ๋ฐ›๊ณ  ์ƒ์„ฑ ํ›„ ํ˜ธ์ถœ์€ ๋‹ค๋ฅด๊ฒŒ ์ ‘๊ทผํ•˜์—ฌ ๋™๊ธฐํ™” ์˜ค๋ฒ„ํ—ค๋“œ๋„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

๋ฐฉ๋ฒ•5 enum

// ์ดํŽ™ํ‹ฐ๋ธŒ์ž๋ฐ” item3
public enum EnumSingleton { 
     INSTANCE; 
     public static EnumSingleton getInstance() { 
          return INSTANCE; 
     } 
}

์ด์ „ ๋ฐฉ์‹์— ๋น„ํ•ด ๋” ๊ฐ„๊ฒฐํ•˜๊ณ , ์ง๋ ฌํ™”๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ†ตํ•œ ๊ณต๊ฒฉ์—๋„ ์•ˆ์ „ํ•˜๋‹ค. ์›์†Œ๊ฐ€ ํ•˜๋‚˜๋ฟ์ธ enum ์ž๋ฃŒํ˜•์ด์•ผ๋ง๋กœ Singleton ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.


Singleton ๋‹จ์ 

1. ํด๋ž˜์Šค๋ฅผ Singleton ์œผ๋กœ ๋งŒ๋“ค๋ฉด ํด๋ผ์ด์–ธํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

Singleton ์ด ์–ด๋–ค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฉด ๊ฐ€์งœ ๊ตฌํ˜„์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

2. ๋ฆฌํ”Œ๋ ‰์…˜ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด private ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณต๊ฒฉ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

AccessibleObject.setAccessible ๋ฉ”์„œ๋“œ์˜ ๋„์›€์„ ๋ฐ›์•„ ๊ถŒํ•œ ํš๋“์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Constructor<?> con = Private.class.getDeclaredConstructors()[0];
con.setAccessible(true);
Private p = (Private) con.newInstance();

3. Singleton ํด๋ž˜์Šค๋ฅผ ์ง๋ ฌํ™” ๊ฐ€๋Šฅ(Serializable) ํด๋ž˜์Šค๋กœ ๋งŒ๋“œ๋ ค๋ฉด ํด๋ž˜์Šค ์„ ์–ธ์— implements Serializable์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค.

(์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” item89) Singleton ํŠน์„ฑ์„ ์œ ์ง€ํ•˜๋ ค๋ฉด ๋ชจ๋“  ํ•„๋“œ๋ฅผ transient๋กœ ์„ ์–ธํ•˜๊ณ  readResolve() ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ง๋ ฌํ™”๋œ ๊ฐ์ฒด๊ฐ€ ์—ญ์ง๋ ฌํ™”๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ๊ธฐ๊ฒŒ๋œ๋‹ค.

public class Elvis implements Serializable {
	
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    
	// Singleton ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ readResolve ๊ตฌํ˜„ 
	private Object readResolve() { 
    	// ๋™์ผํ•œ Elvis ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•˜๋Š” ๋™์‹œ์—, ๊ฐ€์งœ Elvis ๊ฐ์ฒด๋Š” GC๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค. 
    	return INSTANCE; 
	}
}

์—ญ์ง๋ ฌํ™”ํ•  ๊ฐ์ฒด์˜ ํด๋ž˜์Šค์— ์ œ๋Œ€๋กœ ์„ ์–ธ๋œ readResolve() ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ, ์—ญ์ง๋ ฌํ™”๊ฐ€ ๋๋‚˜์„œ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

4. private ์ƒ์„ฑ์ž๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์†ํ•  ์ˆ˜ ์—†๋‹ค.

(ํ† ๋น„ ์Šคํ”„๋ง) ๊ธฐ์ˆ ์ ์ธ ์„œ๋น„์Šค๋งŒ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์ƒ๊ด€์—†๊ฒ ์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋กœ์ง์„ ๋‹ด๊ณ  ์žˆ๋Š” ์ผ๋ฐ˜ ์˜ค๋ธŒ์ ํŠธ์˜ ๊ฒฝ์šฐ Singleton ์œผ๋กœ ๋งŒ๋“ค์—ˆ์„ ๋•Œ ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ์„ค๊ณ„์˜ ์žฅ์ ์„ ์ ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค๋Š” ์ ์€ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋‹ค.

5. ์„œ๋ฒ„ํ™˜๊ฒฝ์—์„œ๋Š” Singleton ์ด ํ•˜๋‚˜๋งŒ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค.

(ํ† ๋น„ ์Šคํ”„๋ง) ์„œ๋ฒ„์—์„œ ํด๋ž˜์Šค ๋กœ๋”๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•˜๊ณ  ์žˆ๋Š๋ƒ์— ๋”ฐ๋ผ์„œ Singleton ํด๋ž˜์Šค์ž„์—๋„ ํ•˜๋‚˜ ์ด์ƒ ์˜ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ JVM์— ๋ถ„์‚ฐ๋ผ์„œ ์„ค์น˜๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ์—๋„ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— Singleton ์œผ๋กœ์„œ์˜ ๊ฐ€์น˜๊ฐ€ ๋–จ์–ด์ง„๋‹ค.

6. Singleton ์˜ ์‚ฌ์šฉ์€ ์ „์—ญ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋žŒ์งํ•˜์ง€ ๋ชปํ•˜๋‹ค.

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


์ด์ฐฌํฌ (MarkiiimarK)
Never Stop Learning.