# [๋””์ž์ธ ํŒจํ„ด] ์ƒ์„ฑ ํŒจํ„ด - ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด
Study Repository

[๋””์ž์ธ ํŒจํ„ด] ์ƒ์„ฑ ํŒจํ„ด - ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด

by rlaehddnd0422

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด๋ž€?

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

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์‚ฌ์šฉ ์ด์œ 

  1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์…˜ ์ปค๋„ฅ์…˜ ํ’€๊ณผ ๊ฐ™์ด ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ๋งŒ๋“ค์–ด ๋‘๊ณ  ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ์žฌํ™œ์šฉํ•˜์—ฌ ํ•„์š”๋กœ ํ•˜๋Š” ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์ด, ์ธ์Šคํ„ด์Šค๋ฅผ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์„ ๋•Œ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์ž์› ์‚ฌ์šฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด.

 

์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์ƒ์„ฑ ๋ฐฉ๋ฒ•

0. ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹

  • ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‘ ๊ฐœ ์ด์ƒ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ง‰์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์„ ์ ์œผ๋กœ ๊ฐ์ฒด ์ƒ์„ฑ์„ ์œ„ํ•œ new ํ‚ค์›Œ๋“œ์— ์ œ์•ฝ์กฐ๊ฑด์„ ๊ฑธ์–ด์ค˜์•ผ ํ•˜๊ณ , ๋งŒ๋“ค์–ด์ง„ ๋‹จ์ผ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
public class Main {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1 == singleton2); // True
}
static class Singleton {
private static final Singleton INSTANCE; // static ์˜์—ญ์— ๋ฏธ๋ฆฌ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋†“์€ ํ›„, ๊ฐ์ฒด ์ƒ์„ฑ์„ getIntance()๋กœ ํ˜ธ์ถœํ•˜์—ฌ, ํ•ญ์ƒ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ์„ค์ •
public static Singleton getInstance() {
if(INTANCE == null) {
INSTANCE = new SingleTon();
}
return Singleton.INSTANCE;
}
// ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ง‰์•„์ฃผ๊ธฐ
private Singleton{}(
// ๋‚ด๋ถ€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ๋ฅผ ๋˜์ ธ ๋‚ด๋ถ€์—์„œ๋„ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€ ๋ชปํ•˜๋„๋ก ์„ค์ •.
throw new AssertionError();
)
}
}
  • ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ Thread Safe ํ•˜์ง€ ์•Š๋‹ค๋Š” ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ์žˆ์Œ.
public static Singleton getInstance() {
// Thread A์™€ Thread B์—์„œ ๋™์‹œ์— getInstance()๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด if ์กฐ๊ฑด๋ถ„๊ธฐ๋ฌธ์ด A์™€ B์—์„œ ๋ชจ๋‘ ํ†ต๊ณผํ•˜๋Š” ๊ฒฝ์šฐ SingleTon์ด ๊นจ์ง€๊ฒŒ ๋จ.
if(INTANCE == null) {
INSTANCE = new SingleTon();
}
return Singleton.INSTANCE;
}
  • ์œ„ ์ฝ”๋“œ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— getInstance()๋ฅผ ๋™์‹œ์— ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ Singleton ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‘ ๊ฐœ ์ƒ์„ฑ๋˜์–ด ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด ๊นจ์งˆ ์šฐ๋ ค๊ฐ€ ์žˆ์Œ.

Thread Safeํ•œ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ด…์‹œ๋‹ค.

 

1. static + ์ค‘์ฒฉํด๋ž˜์Šค(ํ™€๋”) ๋ฐฉ์‹

public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private static final Singleton SINGLETON_OBJECT = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.SINGLETON_OBJECT;
}
}
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹น ๋‹จ ํ•˜๋‚˜ + SingletonHoder๋ฅผ ์‹ค์ œ ์‚ฌ์šฉํ•  ๋•Œ๊นŒ์ง€ ์ดˆ๊ธฐํ™”๋ฅผ ๋ฏธ๋ฃธ.
  • JVM์˜ ํด๋ž˜์Šค ๋กœ๋”์— ์˜ํ•ด ๋กœ๋“œ๋  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด ์ƒ์„ฑ๋จ.
  • ์ •์  ์ดˆ๊ธฐํ™”๋กœ ์ƒ์„ฑ๋˜๋ฏ€๋กœ Thread Safeํ•˜๋‹ค๋Š” ์žฅ์ .
    • Thread Safe : ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ getInstance()๋ฅผ ํ˜ธ์ถœํ•ด๋„ ๋‹จ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ๋ฆฌํ„ด.

 

2. Eager init ๋ฐฉ์‹

public class Singleton {
private static final Singleton SINGLETON_OBJECT = new Singleton();
private Singleton() {
}
public static synchronized Singleton getInstance() {
return SINGLETON_OBJECT;
}
}
  • ๋ฏธ๋ฆฌ static ์˜์—ญ์— ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด๋‘๋Š” ๋ฐฉ์‹.
  • ๋งŒ์•ฝ ์ƒ์„ฑ ๋น„์šฉ์ด ํฌ๊ณ , ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„์˜ ์šฐ๋ ค๊ฐ€ ์žˆ์Œ.
  • ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•ด์ค„ ์ˆ˜ ์žˆ์Œ.

 

3. Synchronized lazy init ๋ฐฉ์‹

static class Singleton {
private static Singleton singletonObject;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (singletonObject == null) {
singletonObject = new Singleton();
}
return singletonObject;
}
}
  • ๋‹จ์ˆœํžˆ synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ getInstance() ๋ฉ”์†Œ๋“œ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์ด ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•.
  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด ๋™๊ธฐํ™” ์ž‘์—…์ด ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ €ํ•˜ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.

 

4. double check locking ๋ฐฉ์‹

  • volatile ํ‚ค์›Œ๋“œ์™€ ๋”๋ธ” ์ฒดํฌ๋ฅผ ํ†ตํ•œ synchronized ํ‚ค์›Œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ๋งŒ ๋™๊ธฐํ™” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•.
  • volatile keyword๋Š” Java ๋ณ€์ˆ˜๋ฅผ Main Memory์— ์ €์žฅํ•˜๊ฒ ๋‹ค๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๋Š” ํ‚ค์›Œ๋“œ
  • ์•ž์„  synchronized lazy init ๋ฐฉ์‹ ์ฒ˜๋Ÿผ getInstance()๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋™๊ธฐํ™” ์ž‘์—…์— ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, "์ตœ์ดˆ" ์ดˆ๊ธฐํ™” ์‹œ์—๋งŒ ๋™๊ธฐํ™” ์ž‘์—… ์ˆ˜ํ–‰.
  • JVM ๋ฒ„์ „์ด 1.5 ์ด์ƒ์ธ ๊ฒฝ์šฐ์—๋งŒ ์ ์šฉ ๊ฐ€๋Šฅ
public class Singleton {
// volatile ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ
private static volatile Singleton singletonObject;
private Singleton() {
}
public static Singleton getInstance() {
if (singletonObject == null) {
// if ๋ฌธ ์ง„์ž… ์‹œ์—๋งŒ Singleton ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋™๊ธฐํ™” ์ž‘์—… ์ˆ˜ํ–‰
synchronized (Singleton.class) {
if (singletonObject == null) {
singletonObject = new Singleton();
}
}
}
return singletonObject;
}
}

 

5. Enum ๋ฐฉ์‹

  • enum ํƒ€์ž…์œผ๋กœ ์‹ฑ๊ธ€ํ†ค์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•.
  • ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, Serialize ๋˜๋Š” Reflection ๊ณต๊ฒฉ์—์„œ๋„ ์‹ฑ๊ธ€ํ†ค์ด ๊นจ์ง€๋Š” ๊ฒƒ์„ ์™„๋ฒฝํžˆ ๋ง‰์„ ์ˆ˜ ์žˆ์Œ.
  • ๋งŒ๋“œ๋ ค๋Š” ์‹ฑ๊ธ€ํ†ค์ด enum์™ธ์˜ ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ด ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (๋‹ค๋งŒ, enum Singleton implements ~์™€ ๊ฐ™์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ตฌํ˜„ํ•˜๋„๋ก ์„ ์–ธํ•  ์ˆ˜๋Š” ์žˆ์Œ)
public enum Singleton {
INSTANCE;
}

 

<์ฐธ๊ณ  ์ž๋ฃŒ>

 

[Java] ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด(Singleton Pattern) - ๊ฐœ๋… ๋ฐ ์˜ˆ์ œ

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

ittrue.tistory.com

 

๋ธ”๋กœ๊ทธ์˜ ํ”„๋กœํ•„ ์‚ฌ์ง„

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

Study Repository

rlaehddnd0422

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