์ถ์ฒ
ChatGPT
https://simyeju.tistory.com/121
https://www.initgrep.com/posts/design-patterns/thread-safety-in-java-singleton-pattern
F-Lab Android Pepe ๋ฉํ ๋
๊ด๋ จ ๊ฐ๋
Singleton ํจํด
๊ฐ์ฒด๋ฅผ ์ค์ง ํ๋๋ง ์์ฑํ๋๋ก ๋ณด์ฅํ๋ ๋์์ธ ํจํด. ํ๋ก๊ทธ๋จ ์ ์ฒด์ ํ๋์ ์ธ์คํด์ค๋ง ํ์ํ๊ณ , ๊ทธ ์ธ์คํด์ค์ ์ ์ญ์ ์ผ๋ก ์ ๊ทผํ ์ ์๋๋กํ๋ ์ํฉ์์ ์ ์ฉํ๋ค.
-> OOP ํ๊ฒฝ์์ ์ ์ญ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ด์ ๋์จ ๊ฒ
Singleton ๊ฐ์ฒด
์ฑ๊ธํค ํจํด์ ๋ฐ๋ผ ์์ฑ๋ ๊ฐ์ฒด. ํด๋น ํด๋์ค์ ์ ์ผํ ์ธ์คํด์ค๋ฅผ ์๋ฏธํ๋ค.
์ฑ๊ธํค ํจํด์ ์ฌ์ฉํ๋ ๋ํ์ ์ธ ๊ฒฝ์ฐ
- ์ค์ ๊ด๋ฆฌ : ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ๊ฑธ์ณ ์ผ์ ํ ์ค์ ๊ฐ์ ์ ์งํ ํ์๊ฐ ์์ ๋
- ๋ก๊ทธ ๊ธฐ๋ก : ํ๋ก๊ทธ๋จ ๋ด์ ๋ชจ๋ ๋ก๊ทธ๊ฐ ๋์ผํ ๋ก๊ทธ ํ์ผ์ ๊ธฐ๋ก๋์ด์ผ ํ ๋
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๊ด๋ฆฌ : ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ํ๋์ ์ธ์คํด์ค๋ก ๊ด๋ฆฌํ๊ณ ๊ณต์ ํ ๋
Thread-Safe ์๋ฏธ
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ๋ ค๊ณ ํ ๋๋, ํ๋ก๊ทธ๋จ์ ์คํ ๊ฒฐ๊ณผ๊ฐ ์ ํํ๊ณ ์์ธก ๊ฐ๋ฅํ ์ํ๋ก ์ ์ง๋๋ ๊ฒ
์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ Thread-Safeํ๊ฒ ๋ง๋ค์ด์ผ ํ๋ ์ด์
๋ฉํธ์ค๋ ๋ ํ๊ฒฝ์์ ์ธ์คํด์ค์ ์ ์ผ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด์. ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ getInstance() ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ผ๋ฉฐ, ์ด๋ ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ ๋ฒ ์์ฑ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ์คํ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค.
1. ๋์์ฑ ๋ฌธ์
์ฑ๊ธํค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๊ฒฝ์ฐ, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ getInstance() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์์ง ์ธ์คํด์ค์ฌ ์์ฑ๋์ง ์์์ ๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์์ฑ ์๋๋ฅผ ํ ์ ์๋ค.
์ด ๊ฒฝ์ฐ, ์๋ก ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๊ฐ๊ธฐ ๋ค๋ฅธ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋ ์ ์์ด ์ฑ๊ธํค์ ์ ์ผ์ฑ ์์น์ด ๊นจ์ง๋ค.
2. ๋ฐ์ดํฐ ์ผ๊ด์ฑ ์ ์ง
์ฑ๊ธํค ๊ฐ์ฒด๋ ์ฃผ๋ก ์ค์ , ๋ก๊น , ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, ๋ฆฌ์์ค ๊ด๋ฆฌ ๋ฑ์ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ฉฐ, ์ฌ๋ฌ ๋ถ๋ถ์์ ์ ๊ทผ์ด ์ผ์ด๋๋ฏ๋ก ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ด ์ค์ํ๋ค.
- ๋ฐ์ดํฐ ์ผ๊ด์ฑ Data Consistency : ์ฌ๋ฌ ์ค๋๋ ๋๋ ํ๋ก์ธ์ค๊ฐ ๋์์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ๋ ๋ฐ์ดํฐ๊ฐ ํญ์ ์ ํํ๊ณ ์์ธก ๊ฐ๋ฅํ ์ํ๋ก ์ ์ง๋๋ ๊ฒ
Thread-Safeํ์ง ์๋ค๋ฉด, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํด ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ค ํ ๋, ์๋ชป๋ ๋ฐ์ดํฐ ์ํ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๊ฒฝํฉ ์ํ(race condition)์ด ์ผ์ด๋ ์ ์๋ค.
- ๊ฒฝํฉ ์ํ Race Condition : ์ฌ๋ฌ ์ค๋ ๋ ๋๋ ํ๋ก์ธ์ค๊ฐ ๋์์ ๊ณต์ ์์์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ๋ ค ํ ๋ ๋ฐ์ํ๋ ๋ฌธ์ . ์์ ์ ์คํ ์์๊ฐ ์คํ๋ง๋ค ๋ฌ๋ผ์ง๋ฉด์ ์์ธกํ ์ ์๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์๋ค.
3. ๋ฆฌ์์ค ๋ญ๋น ๋ฐฉ์ง
์ฑ๊ธํต ํจํด์ ์ฃผ์ ์ฅ์ ์ ๊ฐ์ฒด๋ฅผ ํ ๋ฒ๋ง ์์ฑํด ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ์ ์ฝํ๋ ๊ฒ์ด๋ค.
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ Thread-Safeํ์ง ์์ผ๋ฉด ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ๋ฒ ์์ฑํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ๊ณ , ์ด๋ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ ๋ฆฌ์์ค ์ฌ์ฉ ์ฆ๊ฐ๋ก ์ด์ด์ง ์ ์๋ค.
Thread-Safeํ ์ฑ๊ธํค ๊ฐ์ฒด ์์ฑ ๋ฐฉ๋ฒ
1. ์ด๋ฅธ ์ด๊ธฐํ Eager Initialization
ํด๋์ค ๋ก๋ฉ ์์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํด ๊ฐ๋จํ๊ณ ์ค๋ ๋์ ์์ ํ๋ค.
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
// private constructor to prevent instantiation
}
public static Singleton getInstance() {
return instance;
}
}
ํ๋ก๊ทธ๋จ ์คํ ์, ํด๋์ค ๋ก๋์ ์ํด ํด๋์ค๊ฐ ๋ก๋ฉ๋ ๋ static ์ ์ด์์ ์ํด ๋ฏธ๋ฆฌ ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๋ฐฉ์
์ฅ์
๊ตฌํ์ด ๋งค์ฐ ๊ฐ๋ํ๋ฉฐ, ํด๋์ค ๋ก๋ฉ ์์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ฏ๋ก ์ค๋ ๋ ์์ ์ฑ์ด ๋ณด์ฅ๋๋ค.
๋จ์
๊ฐ์ฒด๊ฐ ํญ์ ์์ฑ๋๋ค. ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์์ ์ ์๋ค.
๐ฎ ๋ฉํ ๋์ ํตํด ํด๋์ค ๋ก๋ ์์ ์ ๊ณ ๋ คํด์ผ ํ๋ฉด, 1๋ฒ์ Eager Initialization ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํํ๋ ๊ฒ๊ณผ 5๋ฒ์ ์ ์ ๋ด๋ถ ํด๋์ค๋ฅผ ์ด์ฉํด ๊ตฌํํ๋ ๊ฒ์ ํด๋์ค ๋ก๋์ INSTANCE ์์ฑ ์์ ์ ๋์ผํ๋ค๋ ๊ฒ์ ์์๋ค.(1๋ฒ๊ณผ 5๋ฒ์ด ๋ด๋ถ์ ์ผ๋ก๋ ๋๊ฐ๋ค๋ ๊ฑฐ) ํด๋น ๋ด์ฉ ์ค๋ช ์ 5๋ฒ์์ ํ๊ฒ ๋ค.
2. Lazy Initialization
ํ์ํ ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐฉ์. ๋จ์ํ๊ฒ ๊ตฌํํ๋ฉด ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ์์ ํ์ง ์๋ค.
public class Singleton {
private static Singleton instance;
// private ์์ฑ์
private Singleton() {
}
// ์ธ์คํด์ค ๋ฐํ ๋ฉ์๋
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- ๋จ์ : ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ getInstacne()๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ ๋ฒ ์์ฑ๋ ์ ์๋ ๋ฌธ์ ๊ฐ ์๋ค.
3. Synchronized๋ฅผ ์ฌ์ฉํ Lazy Initialization
getInstance() ๋ฉ์๋๋ฅผ synchronized๋ก ๋ง๋ค์ด ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ์ง ๋ชปํ๊ฒ ํ๋ค.
public class Singleton {
private static Singleton instance;
// private ์์ฑ์
private Singleton() {
}
// ๋๊ธฐํ๋ ์ธ์คํด์ค ๋ฐํ ๋ฉ์๋
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
์ฅ์
์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ค.
๋จ์
getInstance() ๋ฉ์๋ ํธ์ถ ์๋ง๋ค lock์ ๊ฑธ์ด ๋๊ธฐํ๋ฅผ ์ํํ๋ฏ๋ก ์ฑ๋ฅ์ด ์ ํ๋ ์ ์๋ค.
4. Double-Checked Locking
synchronized๋ก ์ธํ ์ฑ๋ฅ ์ ํ๋ฅผ ์ค์ด๊ธฐ ์ํด ๊ณ ์๋ ๋ฐฉ์์ด๋ค. ์ธ์คํด์ค๋ฅผ ์ฒ์ ์์ฑํ ๋๋ง ๋๊ธฐํ๋ฅผ ์ํํ๋ค.
public class Singleton {
private static volatile Singleton instance;
// private ์์ฑ์
private Singleton() {
}
// ์ธ์คํด์ค ๋ฐํ ๋ฉ์๋
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
volatile ํค์๋๋ฅผ ์ฌ์ฉํด ์ธ์คํด์ค๋ฅผ volatile๋ก ์ ์ธํ ์ด์ ๋, ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๊ณผ์ ์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์๋ชป ์ฐธ์กฐํ์ง ์๋๋ก ํ๊ธฐ ์ํจ์ด๋ค. ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๋์ CPU ๋ช ๋ น์ด๊ฐ ์ต์ ํ๋์ด ์ค๊ฐ ์ํ๋ฅผ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ณผ ์ ์๋ ๊ฐ๋ฅ์ฑ์ ๋ฐฉ์งํ๋ค.
- Double-Checked Locking ๋ฐฉ์์์ volatile ํค์๋๊ฐ ์ฌ์ฉ๋๋ ์ด์ ๋ ๊ฐ์ฒด์ ์์ฑ ๊ณผ์ ์ด ์์์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ์ฌ๋ฌ ๋จ๊ณ(๋ฉ๋ชจ๋ฆฌ ํ ๋น -> ์์ฑ์ ํธ์ถํด ๊ฐ์ฒด ์ด๊ธฐํ -> ๋ณ์์ ์ฐธ์กฐ ํ ๋น)๋ก ์ด๋ฃจ์ด์ง๋๋ฐ, ์ด ๊ณผ์ ์ด ์ค๊ฐ ์ํ์ผ ๋์๋ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ฉด ์์ ํ ์ด๊ธฐํ๋์ง ์์ ๊ฐ์ฒด์ ์ ๊ทผํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. volatile ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๊ฐ์ฒด์ ์ฌ์ ๋ ฌ(๋ช ๋ นํ ์ต์ ํ) ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ณ , ๊ฐ์ฒด๊ฐ ์์ ํ ์์ฑ๋ ํ์ ๋ค๋ฅธ ์ค๋ ๋์์ ์ฐธ์กฐํ๋๋ก ๋ณด์ฅํ๋ค.
3๋ฒ์ getInstance() ๋ฉ์๋์ ์ถ๊ฐํ synchronized๋ฅผ ๋นผ๋ฉด์ ์ค๋ฒํค๋๋ ์ค์ธ๋ค.
null ์ฒดํฌ๋ฅผ ๋ ๋ฒํ๋ ์ด์ : ๋ถํ์ํ ๋๊ธฐํ๋ฅผ ์ค์ด๊ณ ์ฑ๋ฅ์ ์ต์ ํ๊ณ ํ๊ธฐ ์ํจ. ์ฑ๊ทธํค ๊ฐ์ฒด๊ฐ ์ด๋ฏธ ์์ฑ๋ ์ดํ์๋ ๋๊ธฐํ์์ด ๋น ๋ฅด๊ฒ ๋ฐํํ ์ ์๋ค.
- ์ฒซ ๋ฒ ์งธ null ์ฒดํฌ์ ์ญํ
- ๋ถํ์ํ ๋๊ธฐํ ๋ฐฉ์ง : ์ฒซ ๋ฒ์งธ if(instance == null) ์ฒดํฌ๋, ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ธ์คํด์ค๊ฐ ์ด๋ฏธ ์์ฑ๋์ด ์์ ๋ ๋๊ธฐํ ๋ธ๋ก์ ๋ค์ด๊ฐ์ง ์๋๋ก ํ๊ธฐ ์ํ ๊ฒ์ด๋ค. ์ฆ, ์ด๋ฏธ ์ฑ๊ธํค ๊ฐ์ฒด๊ฐ ์์ฑ๋ ์ํ์์๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋๊ธฐํ ๋ธ๋ก์ ์ ๊ทผํ์ง ์๊ฒ ํด ์ฑ๋ฅ ์ ํ๋ฅผ ๋ฐฉ์งํ๋ค.
- ์ฑ๊ธํค ๊ฐ์ฒด๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ ๊ฒฝ์ฐ, ์ด ์กฐ๊ฑด๋ฌธ์์ ๋น ๋ฅด๊ฒ ๋ฐํํ ์ ์์ผ๋ฏ๋ก ๋๊ธฐํ๋ฅผ ์ํํ์ง ์๊ณ ๋ ๋น ๋ฅธ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
- ๋ ๋ฒ์งธ null ์ฒดํฌ์ ์ญํ
- ์์ ํ ์ธ์คํด์ค ์์ฑ ๋ณด์ฅ : ์ฒซ ๋ฒ์งธ null ์ฒดํฌ๋ฅผ ํต๊ณผํ ํ, ๋๊ธฐํ ๋ธ๋ก์ ๋ค์ด๊ฐ์ ๋ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ด๋ฏธ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ ๊ฐ๋ฅ์ฑ์ ๋ฐฉ์งํ๊ธฐ ์ํ ๊ฒ.
- ์๋ฅผ ๋ค์ด,
- ๋ ๊ฐ์ ์ค๋ ๋ A์ B๊ฐ ๋์์ ์ฒซ ๋ฒ์งธ null ์ฒดํฌ๋ฅผ ํต๊ณผํ๋ค๊ณ ๊ฐ์ ํ๋ฉด,
- ๋ ์ค๋ ๋๊ฐ ๋๊ธฐํ ๋ธ๋ก์ ์ง์ ํ ์ ์๋ค. ์ด๋ ์ค๋ ๋ A๊ฐ ๋จผ์ ๋๊ธฐํ ๋ธ๋ก์ ์ง์ ํด ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ
- ๊ทธ ํ ์ค๋ ๋ B๋ ๋์ผํ ๋ธ๋ก ์์์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ค ํ ๋, ๋ ๋ฒ์งธ if(instance == null) ์ฒดํฌ๋ฅผ ์ํํด ์ด๋ฏธ ์์ฑ๋ ์ธ์คํด์ค๊ฐ ์์ผ๋ฉด ๋ค์ ์์ฑํ์ง ์๋๋ก ํ๋ค.
์ฅ์
์ธ์คํด์ค๋ฅผ ์ฒ์ ์์ฑํ ๋๋ง ๋๊ธฐํ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ด์๋ฅผ ์ค์ผ ์ ์๋ค.
5. ์ ์ ๋ด๋ถ ํด๋์ค Static Inner Class
Lazy Initialization์ ๋ณด์ฅํ๋ฉด์๋, JVM์ ํด๋์ค ๋ก๋ฉ ์์น์ ์ด์ฉํด ์์ฐ์ค๋ฝ๊ฒ ์ค๋ ๋ ์์ ์ฑ์ ํ๋ณดํ๋ ๋ฐฉ์์ด๋ค.
public class Singleton {
// private ์์ฑ์
private Singleton() {
}
// ์ ์ ๋ด๋ถ ํด๋์ค
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
// ์ธ์คํด์ค ๋ฐํ ๋ฉ์๋
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
์ฅ์
ํด๋์ค ๋ก๋ฉ ์์ ์ Singleton ํด๋์ค๊ฐ ์๋ Holder ํด๋์ค๊ฐ ๋ก๋๋๋ฏ๋ก Lazy Initialization์ ์ง์ํ๋ฉฐ, JVM ํด๋์ค ๋ก๋ฉ ๋งค์ปค๋์ฆ์ ์ด์ฉํด ์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅํ๋ค. ์ด ๋ฐฉ์์ ๊ฐ๊ฒฐํ๋ฉด์๋ ์ฑ๋ฅ ์ ํ๊ฐ ์๋ ๊ฒ์ด ํฐ ์ฅ์ ์ด๋ค.
๋ด๋ถ Static ํด๋์ค๋ฅผ ์ด์ฉํด ์ฐธ์กฐ๋๊ธฐ ์ ๊น์ง ๋ด๋ถ ํด๋์ค๋ฅผ ๋ก๋ํ์ง ์๋๋ค.
Static final ์ธ์คํด์ค๋ก ์ฑ๊ธํด ํด๋์ค๊ฐ ์ ์ธ๋์ด, ์ธ์คํด์ค๊ฐ ํ ๋ฒ๋ง ์ด๊ธฐํ๋๊ณ , ์ดํ ์ ๊ทผ ์ ๋์ผํ ์ธ์คํด์ค๊ฐ ๋ฐํ๋๋ ๊ฑธ ๋ณด์ฆํ๋ค.
- ์ด ๋ฐฉ์์ด Lazy Initialization์ ์ง์ํ๋ ์ด์
- Lazy Loading ํน์ฑ
- Holder ํด๋์ค๋ getInstance() ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋ ์ต์ด๋ก ๋ก๋๋๋ค. ์ด๋ Holder ํด๋์ค๊ฐ ๋ก๋๋๋ฉด์ ๊ทธ ์์ ์๋ INSTACE๋ ์ด๊ธฐํ๋๋ค.
- Singleton ํด๋์ค ์์ฒด๋ ๋ก๋๋๋๋ผ๋ ๋ด๋ถ์ Holder ํด๋์ค๋ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๋ก๋๋์ง ์์ผ๋ฏ๋ก, INSTANCE๋ ํ์ํ ๋๋ง ์์ฑ๋๋ค. ์ด๋ ๊ฒ Lazy Initialization์ด ์์ฐ์ค๋ฝ๊ฒ ๊ตฌํ๋๋ค.
- JVM ํด๋์ค ๋ก๋ฉ์ ์ค๋ ๋ ์์ ์ฑ
- JVM์ ํด๋์ค ๋ก๋ฉ๊ณผ ์ด๊ธฐํ ๊ณผ์ ์ด ์ค๋ ๋ ์์ ํ๋๋ก ๋ณด์ฅํ๋ค. ์ฆ, ํด๋์ค๊ฐ ๋ก๋๋๊ณ ์ด๊ธฐํ๋๋ ๊ณผ์ ์ JVM์ ์ํด ํ ๋ฒ๋ง ์ด๋ฃจ์ด์ง๋ฉฐ, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ๋๋ผ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
- ๋ฐ๋ผ์ Holder ํด๋์ค๊ฐ ๋ก๋๋ ๋ INSTANCE๊ฐ ์ด๊ธฐํ๋๋ฉด, ์ด ๊ณผ์ ์ด ์ค๋ ๋ ์์ ํ๊ธฐ ๋๋ฌธ์ ์ถ๊ฐ์ ์ธ ๋๊ธฐํ ์์ด๋ ์์ ํ๊ฒ ์ฑ๊ธํต ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์๋ค.
- Lazy Loading ํน์ฑ
๋ผ๊ณ ์จ๋จ์ผ๋, ํด๋์ค ๋ก๋ ์์ ์ ๊ณ ๋ คํด๋ณด๋ฉด, 1๋ฒ๊ณผ 5๋ฒ์ผ๋ก ๊ตฌํํ ์ฑ๊ธํค ๊ฐ์ฒด๋ค์ getInstance()๋ฅผ ์ต์ด ํธ์ถ ์์ ๋ด๋ถ์ ์ผ๋ก ๋์ผํ๊ฒ ๋์๊ฐ๋ค.
์ฑ๊ธํค ๊ฐ์ฒด๋ Singleton.getInstance() ์ฝ๋๋ฅผ ํ ๋ฌถ์์ผ๋ก ํธ์ถํด ์ฌ์ฉํ๋ค. ํด๋์ค ๋ก๋ ์์ ์ ํด๋์ค๊ฐ ์ฒ์ ์ฌ์ฉ๋ ๋์ด๊ธฐ ๋๋ฌธ์, ๋ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑํ Singleton ๊ฐ์ฒด๋ค์ ์ต์ด๋ก ํธ์ถํ๋ Singleton.getInstance() ์ฝ๋ ์ฌ์ฉ์์ 5๋ฒ์ผ๋ก ๊ตฌํ๋ ์ ์ ๋ด๋ถ ํด๋์ค๋ ์ด ์์ ์์ ๋ก๋๋๋ค. 5๋ฒ์ ์ฅ์ ์ด๋ผ๋ Lazy Loading์ด ๋ฑํ ๋๋ฌ๋์ง ์๋๋ค.
6. Enum
์๋ฐ์ enum์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธํค์ ํน์ฑ์ ๊ฐ์ง๋ฏ๋ก, ์ฑ๊ธํค ํจํด ๊ตฌํ์ ์ฝ๋์ ๊ฐ๊ฒฐ์ฑ, ์ง๋ ฌํ ์์ ์ฑ, ๊ทธ๋ฆฌ๊ณ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์์ ์์ ์ฑ์ ๋ชจ๋ ์ ๊ณตํ๋ค.
public enum Singleton {
INSTANCE;
// ์ํ๋ ๋ฉ์๋๋ ํ๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
public void someMethod() {
System.out.println("Enum Singleton Method Called");
}
}
INSTATNCE : ์ด ํ๋๊ฐ ๋ฐ๋ก ์ฑ๊ธํค ๊ฐ์ฒด์ด๋ค. Singleton.INSTANCE๋ฅผ ํธ์ถํ๋ฉด ์ธ์ ๋ ๋์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.
enum์ JVM์์ ํด๋์ค ๋ก๋ฉ์ ์ค๋ ๋ ์์ ํ๊ฒ ๋ณด์ฅํ๋ฏ๋ก, ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ค.
์ฅ์ :
1. ๊ตฌํ์ด ๊ฐ๊ฒฐํ๋ค.
2. ์ง๋ ฌํ/์ญ์ง๋ ฌํ ๊ณผ์ ์์ ์ฑ๊ธํค์ ์ ์ผ์ฑ์ด ๊นจ์ง ์ํ์ด ์๋ค.
- enum์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ ๊ณผ์
- JVM์ ๋ณด์ฅ
- enum ํ์ ์ ์๋ฐ ์ธ์ด ์ฌ์์ ์ํด ๊ณ ์ ํ๊ฒ ๊ด๋ฆฌ๋๋ค. ์ฆ, ๋ชจ๋ enum ๊ฐ์ JVM์ ์ํด ๋จ ํ๋์ ์ธ์คํด์ค๋ก ๋ณด์ฅ๋๋ฉฐ, ์ด๋ฅผ ํตํด ์ญ์ง๋ ฌํ ์์๋ ๋์ผํ ์ธ์คํด์ค๊ฐ ๋ฐํ๋๋ค.
- ์ด๋ enum์ด ํด๋์ค ๋ก๋ฉ ์ ์๋์ผ๋ก JVM ๋ด์์ ์์์ฒ๋ผ ๊ด๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ๋ค.
- ์ง๋ ฌํ์ ํน๋ณ ์ฒ๋ฆฌ
- enum์ ์๋ฐ์์ ํน๋ณํ ๋ฐฉ์์ผ๋ก ์ง๋ ฌํ๋๊ณ , ์ญ์ง๋ ฌํ๋ ๋๋ ๊ทธ ์ ์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค. ์ด๋ java.io.Serializable ์ธํฐํ์ด์ค์ ์ผ๋ฐ์ ์ธ ๊ตฌํ๊ณผ๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
- enum์ ์ญ ์ง๋ ฌํ ์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๊ณ , ํญ์ JVM์ ์ ์ฅ๋ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ฏ๋ก, ์ ์ผ์ฑ์ด ์ ์ง๋๋ค.
- JVM์ ๋ณด์ฅ
- ๋ค๋ฅธ ์ฑ๊ธํค ๊ฐ์ฒด์์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ ๊ณผ์ ์ ๋ฌธ์
- ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ฑ๊ธํค ๊ฐ์ฒด๋ ๊ธฐ๋ณธ์ ์ธ ์ง๋ ฌํ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ฑ๊ธํ ์ ์ ์ผ์ฑ์ด ๊นจ์ง ์ ์๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ง๋ ฌํ ๊ณผ์
- ์ผ๋ฐ ํด๋์ค์ ๊ฒฝ์ฐ, ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ๋ฉด ๊ฐ์ฒด์ ์ํ๊ฐ ๋ฐ์ดํธ ์คํธ๋ฆผ์ผ๋ก ๋ณํ๋์ด ์ ์ฅ๋๋ค.
- ์ญ์ง๋ ฌํ ๊ณผ์
- ๊ฐ์ฒด๋ฅผ ์ญ์ง๋ ฌํํ๋ฉด, ์ ์ฅ๋ ๋ฐ์ดํธ ์คํธ๋ฆผ์ ํตํด ์๋ก์ด ๊ฐ์ฒด ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ค. ์ด๋ ๊ธฐ์กด์ ์๋ ์ฑ๊ธํค ๊ฐ์ฒด๊ฐ ์๋ ์๋ก์ด ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ ธ์ ์ฑ๊ธํค์ ์ ์ผ์ฑ์ด ๊นจ์ง ์ ์๋ค.
- ์ง๋ ฌํ ๊ณผ์
- ํด๊ฒฐ ๋ฐฉ๋ฒ : readResolve()
- ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ์ผ๋ฐ์ ์ผ๋ก readResolve ๋ฉ์๋๋ฅผ ๊ตฌํํด ์ฑ๊ธํค์ ์ ์ผ์ฑ์ ์ ์งํ๋ค. ์ด ๋ฉ์๋๋ ์ญ์ง๋ คํ๋ ๊ฐ์ฒด ๋์ ๊ธฐ์กด์ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋๋ก ํ๋ค.
- ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ฑ๊ธํค ๊ฐ์ฒด๋ ๊ธฐ๋ณธ์ ์ธ ์ง๋ ฌํ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ฑ๊ธํ ์ ์ ์ผ์ฑ์ด ๊นจ์ง ์ ์๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
private Object readResolve() throws ObjectStreamException {
return instance; // ๊ธฐ์กด์ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ๋ฐํ
}
3. enum์ ํด๋์ค ๋ก๋ฉ ์์ ์์ JVM์ ์ํด ์ด๊ธฐํ๋๋ฉฐ, ์ด ๊ณผ์ ์ ์ค๋ ๋ ์์ ํ๋ฏ๋ก ๋ณ๋์ ๋๊ธฐํ ์ฒ๋ฆฌ๊ฐ ํ์ํ์ง ์๋ค.
- ํด๋์ค ๋ก๋ฉ ์์ ์ ๋๊ธฐํ
- JVM์ ํด๋์ค ๋ก๋ฉ ์ด๊ธฐํ๋ฅผ ํด๋์ค ๋ก๋ ๋ ๋ฒจ์์ ๋๊ธฐํํด ์ฒ๋ฆฌํ๋ค. ์ฆ, ํด๋์ค๊ฐ ์ฌ๋ฌ ์ค๋ ๋์ ์ํด ๋์์ ๋ก๋๋ ์ ์๋ ๊ฒฝ์ฐ๋ผ๋ JVM์ ํ ๋ฒ์ ํ์ ์ค๋ ๋๋ง ํด๋์ค ๋ก๋ฉ ๋ฐ ์ด๊ธฐํ๋ฅผ ํ์ฉํ๋ค.
- ์ด๋ก ์ธํด, enum ํ์ ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ๋๋ผ๋ ์ด๊ธฐํ ๊ณผ์ ์์ ๊ฒฝํฉ ์ํ๋ ๋ฐ์ดํฐ ์ผ๊ด์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
4. enum์ ๋ฆฌํ๋ ์ ์ ์ฌ์ฉํด๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์์ด์ ๋ฆฌํ๋ ์ ๊ณต๊ฒฉ์ ๋ํ ๋ฐฉ์ด๊ฐ ๊ฐ๋ฅํ๋ค.
- enum์ด ๋ฆฌํ๋ ์
์ ํตํด ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์๋ ์ด์
- ๋ฆฌํ๋ ์
์ ํตํ ์์ฑ ์ ํ
- enum์ ์์ฑ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก private์ด๋ฉฐ, ์๋ฐ ๋ฆฌํ๋ ์ API๋ฅผ ํตํด ์ ๊ทผํ๋๋ผ๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์๊ฒ ๋์ด ์๋ค. enum ํ์ ์ java.lang.reflect.Constructor์ newInstance() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋, IllegalArgumentException์ ๋ฐ์์์ผ ์๋ก์ด ์ธ์คํด์ค ์์ฑ์ ๋ง๋๋ค.
- ์๋ฐ ์ธ์ด ์คํ
- enum์ ์์์ฒ๋ผ ์ฌ์ฉ๋๋ ํน๋ณํ ์ ํ์ ํด๋์ค์ด๋ฉฐ, ์ด ํน์ฑ์ ์ ์งํ๊ธฐ ์ํด ๋ฆฌํ๋ ์ ์ ํตํ ์ธ์คํด์ค ์์ฑ์ด ์ ํ๋๋ค. ์ด ์ค๊ณ๋ enum ์ธ์คํด์ค๊ฐ ํญ์ ์ ์ผํ๋ฉฐ, ์ฑ๊ธํค์ ํน์ ์ด ์ ์ง๋๋๋ก ๋ณด์ฅํ๋ ๋ฐ ๋ชฉ์ ์ด ์๋ค.
- ๋ฆฌํ๋ ์
์ ํตํ ์์ฑ ์ ํ
- ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ง๋ ์ฑ๊ธํค ๊ฐ์ฒด์์ ๋ฆฌํ๋ ์
๊ณต๊ฒฉ์ ๋ฐฉ์ดํ๋ ๋ฐฉ๋ฒ
- ๊ธฐ์กด ์ธ์คํด์ค๊ฐ ์๋ ๊ฒฝ์ฐ์ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
- ๋ฆฌํ๋ ์ ์ ํตํ ์์ฑ ๋ฐฉ์ง๋ฅผ ์ํด, ์์ฑ์ ๋ด๋ถ์์ ๊ธฐ์กด ์ธ์คํด์ค ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ ์ด๋ฏธ ์ธ์คํด์ค๊ฐ ์กด์ฌํ๋ค๋ฉด ์์ธ๋ฅผ ๋์ง๋ ๋ฐฉ๋ฒ์ด ์๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ฆฌํ๋ ์ ์ผ๋ก ์์ฑ์๋ฅผ ํธ์ถํ๋๋ผ๋ ๊ธฐ์กด ์ธ์คํด์ค๊ฐ ์์ผ๋ฉด ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
- ๊ธฐ์กด ์ธ์คํด์ค๊ฐ ์๋ ๊ฒฝ์ฐ์ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
public class Singleton {
private static Singleton instance;
// private ์์ฑ์
private Singleton() {
if (instance != null) {
throw new RuntimeException("Use getInstance() method to create");
}
}
// ์ธ์คํด์ค ๋ฐํ ๋ฉ์๋
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
๋จ์ : enum์ ์๋ฐ์์ ํด๋์ค ์์์ ์ง์ํ์ง ์์์ ์ฑ๊ธํค ํด๋์ค๋ฅผ ์์ํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ์ ํฉํ์ง ์๋ค. enum์ ์ธ์คํด์ค ์์ฑ ๋ฐฉ์์ด ๊ณ ์ ์ ์ด๋ผ์, ์ด๊ธฐํ ๊ณผ์ ์์ ํน์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๋ ๋ฑ ๋ ์ ์ฐํ ์ด๊ธฐํ๋ฅผ ์ํ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค.
์๋๋ก์ด๋ ํ๊ฒฝ์์๋ ์ด๋ค ๋ฐฉ์์ด ์ ํฉํ ๊น?
1์. ์ ์ ๋ด๋ถ ํด๋์ค(Static Inner Class) ๋ฐฉ์
๐ค ์ ์ ์ ๋ด๋ถ ํด๋์ค(Static Inner Class) ๋ฐฉ์์ผ๋ก ์ฑ๊ธํด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ก์ด๋ ํ๊ฒฝ์์ ๋ ์ ํฉํ ๊น?
1. ์ฑ๋ฅ ์ต์ ํ
์ ์ ๋ด๋ถ ํด๋์ค ๋ฐฉ์์ ํด๋์ค ๋ก๋ฉ ์์ ์์ JVM์ ์ํด ์ค๋ ๋ ์์ ์ฑ์ ๋ณด์ฅ๋ฐ๊ณ , ๋๊ธฐํ ๋ธ๋ก์ด ํ์ํ์ง ์์ ๋ถํ์ํ ์ฑ๋ฅ ์ ํ๋ฅผ ํผํ ์ ์๋ค.
2. Lazy Initialization
์ธ์คํด์ค๊ฐ ํ์ํ ๋๊น์ง ์ด๊ธฐํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์์์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ด ์๋ ์๋๋ก์ด๋ ํ๊ฒฝ์์ ์ค์ํ๋ค.
3. ์์ ์ฑ
JVM์ด ํด๋์ค ๋ก๋ฉ๊ณผ ์ด๊ธฐํ๋ฅผ ์ค๋ ๋ ์์ ํ๊ฒ ์ฒ๋ฆฌํ๋ฏ๋ก ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ๊ฒ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ๋ณด์ฅํ๋ค.
2์. Enum ๋ฐฉ์
์ฅ์
๊ตฌํ์ ๊ฐ๊ฒฐ์ฑ: enum์ ๊ฐ๊ฒฐํ๊ฒ ์ฑ๊ธํค์ ๊ตฌํํ ์ ์์ผ๋ฉฐ, ์ถ๊ฐ์ ์ธ ์ฝ๋ ์์ด JVM์ด ์ค๋ ๋ ์์ ์ฑ๊ณผ ์ง๋ ฌํ ์์ ์ฑ์ ๋ณด์ฅํ๋ค.์ง๋ ฌ๊ณผ ์์ ์ฑ : ์๋๋ก์ด๋์์ ์ง๋ ฌํ๋ ๊ฐ์ฒด๋ฅผ ๋ณต๊ตฌํ ๋ enum ๋ฐฉ์์ ๋ณ๋์ ์ฒ๋ฆฌ๊ฐ ํ์ ์์ผ๋ฉฐ, ์์ ํ๋ค.๋ฆฌํ๋ ์ ๋ฐฉ์ด :๋ฆฌํ๋ ์ ์ ํตํด ๊ฐ์ฒด ์์์ด ๋ถ๊ฐ๋ฅํด, ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๋นํด ๋ ์์ ํ๋ค.
๋จ์
์ ์ฐ์ฑ ๋ถ์กฑ : enum์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์์ด ๋ถ๊ฐ๋ฅํ๊ณ , ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ์ด๊ธฐํํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ์ ํ์ด ์๋ค. Java์ ํน์ํ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ JVM ์ธ์ด๋ ํน์ํ ์ด๊ธฐํ๊ฐ ํ์ํ ๊ฒฝ์ฐ์๋ ์ฌ์ฉ์ด ์ด๋ ค์ธ ์ ์๋ค.
โญDouble-Checked Locking + volatile ํค์๋ ์ฌ์ฉโญ
์๋๋ก์ด๋์์๋ ์ฑ๊ธํค ์์ฑ์ Context๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๊ฐ์ ธ์์ผ ํ๋ ๊ฒฝ์ฐ๋ค์ด ๊ฝค ์๋ค. getInstance()์ ํ๋ผ๋ฏธํฐ๋ค์ ๋ฐ์์ฌ ์ ์๋ ์์ฑ ํจํด์ ์๋๋ก์ด๋์์ ์ ํฉํ์ง ์๋ค.
๋ํ Double-Checked Locking์ ์ฑ๋ฅ๋ ์ข๋ค.
๊ทธ๋ฌ๋ ์์ฆ์๋ ์๋๋ก์ด๋์์ ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค. ๋์ Hilt๋ฅผ ์ฌ์ฉํ๋ค.
(๋ด์ฉ ์ถ๊ฐ ์์ )
'๊ณณ๊ฐ์์ ์ธ์ฌ๋๋ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฝ๊ธฐ][Android] Could Google Be Forced to Abandon Android? (0) | 2024.09.17 |
---|---|
[Android][Animation] 2์ด๋ง๋ค ๊น๋นก์ด๋ ์ ๋๋ฉ์ด์ . ์ด๊ฐ๋จ ๊ตฌํ (0) | 2023.07.27 |
[Android] Swipe ์ ์ค์ณ ๊ฐ์ง CustomView (0) | 2023.07.20 |
[Kotlin] ํ๋ ฌ์ ๊ณฑ (0) | 2023.07.17 |