์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋ ๋, ์ด๋ค ํด๋์ค๊ฐ ์ต์ด ํ ๋ฒ๋ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋น(static)ํ๊ณ ํด๋น ๋ฉ๋ชจ๋ฆฌ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๋ ํจํด
์ฆ, ์ฑ๊ธํค ํจํด์ 'ํ๋'์ ์ธ์คํด์ค๋ง ์์ฑํ์ฌ ์ฌ์ฉํ๋ ๋์์ธ ํจํด์ด๋ค.
์ธ์คํด์ค๊ฐ ํ์ํ ๋, ๋๊ฐ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง ์๊ณ ๊ธฐ์กด์ ์ธ์คํด์ค๋ฅผ ํ์ฉํ๋ ๊ฒ!
์์ฑ์๊ฐ ์ฌ๋ฌ๋ฒ ํธ์ถ๋๋, ์ค์ ๋ก ์์ฑ๋๋ ๊ฐ์ฒด๋ ํ๋์ด๋ฉฐ ์ต์ด๋ก ์์ฑ๋ ์ดํ์ ํธ์ถ๋ ์์ฑ์๋ ์ด๋ฏธ ์์ฑํ ๊ฐ์ฒด๋ฅผ ๋ฐํ์ํค๋๋ก ๋ง๋๋ ๊ฒ์ด๋ค
(java์์๋ ์์ฑ์๋ฅผ private์ผ๋ก ์ ์ธํด ๋ค๋ฅธ ๊ณณ์์ ์์ฑํ์ง ๋ชปํ๋๋ก ๋ง๋ค๊ณ , getInstance() ๋ฉ์๋๋ฅผ ํตํด ๋ฐ์์ ์ฌ์ฉํ๋๋ก ๊ตฌํํ๋ค)
๋จผ์ , ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋๋ง๋ค ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ํ ๋น๋ฐ์์ผ ํ๋ค. ํ์ง๋ง ํ๋ฒ์ new๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
๋ํ ์ฑ๊ธํค์ผ๋ก ๊ตฌํํ ์ธ์คํด์ค๋ '์ ์ญ'์ด๋ฏ๋ก, ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ค์ด ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ด ๊ฐ๋ฅํ ์ฅ์ ์ด ์๋ค.
์ฃผ๋ก ๊ณตํต๋ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํด์ ์ฌ์ฉํด์ผํ๋ ์ํฉ
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ปค๋ฅ์
ํ, ์ค๋ ๋ํ, ์บ์, ๋ก๊ทธ ๊ธฐ๋ก ๊ฐ์ฒด ๋ฑ
์๋๋ก์ด๋ ์ฑ : ๊ฐ ์กํฐ๋นํฐ ๋ค์ด๋, ํด๋์ค๋ง๋ค ์ฃผ์ ํด๋์ค๋ค์ ํ๋ํ๋ ์ ๋ฌํ๋๊ฒ ๋ฒ๊ฑฐ๋กญ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ด๋์๋ ์ ๊ทผํ๋๋ก ์ค๊ณ
๋ํ ์ธ์คํด์ค๊ฐ ์ ๋์ ์ผ๋ก ํ ๊ฐ๋ง ์กด์ฌํ๋ ๊ฒ์ ๋ณด์ฆํ๊ณ ์ถ์ ๋ ์ฌ์ฉํจ
๊ฐ์ฒด ์งํฅ ์ค๊ณ ์์น ์ค์ ๊ฐ๋ฐฉ-ํ์ ์์น
์ด๋ ๊ฒ์ด ์กด์ฌํ๋ค.
๋ง์ฝ ์ฑ๊ธํค ์ธ์คํด์ค๊ฐ ํผ์ ๋๋ฌด ๋ง์ ์ผ์ ํ๊ฑฐ๋, ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ์ํค๋ฉด ๋ค๋ฅธ ํด๋์ค๋ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋์์ง๊ฒ ๋๋๋ฐ, ์ด๋ ๊ฐ๋ฐฉ-ํ์ ์์น์ด ์๋ฐฐ๋๋ค.
๊ฒฐํฉ๋๊ฐ ๋์์ง๊ฒ ๋๋ฉด, ์ ์ง๋ณด์๊ฐ ํ๋ค๊ณ ํ ์คํธ๋ ์ํํ๊ฒ ์งํํ ์ ์๋ ๋ฌธ์ ์ ์ด ๋ฐ์ํ๋ค.
๋ํ, ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ๋๊ธฐํ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์์ ๋, ์ธ์คํด์ค๊ฐ 2๊ฐ๊ฐ ์์ฑ๋๋ ๋ฌธ์ ๋ ๋ฐ์ํ ์ ์๋ค.
๋ฐ๋ผ์, ๋ฐ๋์ ์ฑ๊ธํค์ด ํ์ํ ์ํฉ์ด ์๋๋ฉด ์ง์ํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํ๋ค. (์ค๊ณ ์์ฒด์์ ์ฑ๊ธํค ํ์ฉ์ ์ํํ๊ฒ ํ ์์ ์ด ์์ผ๋ฉด ๊ด์ฐฎ์)
-
public class ThreadSafe_Lazy_Initialization{ private static ThreadSafe_Lazy_Initialization instance; private ThreadSafe_Lazy_Initialization(){} public static synchronized ThreadSafe_Lazy_Initialization getInstance(){ if(instance == null){ instance = new ThreadSafe_Lazy_Initialization(); } return instance; } }
private static์ผ๋ก ์ธ์คํด์ค ๋ณ์ ๋ง๋ฌ
private์ผ๋ก ์์ฑ์๋ฅผ ๋ง๋ค์ด ์ธ๋ถ์์์ ์์ฑ์ ๋ง์
synchronized ๋๊ธฐํ๋ฅผ ํ์ฉํด ์ค๋ ๋๋ฅผ ์์ ํ๊ฒ ๋ง๋ฌ
ํ์ง๋ง, synchronized๋ ํฐ ์ฑ๋ฅ์ ํ๋ฅผ ๋ฐ์์ํค๋ฏ๋ก ๊ถ์ฅํ์ง ์๋ ๋ฐฉ๋ฒ
-
1๋ฒ์ ์ฑ๋ฅ์ ํ๋ฅผ ์ํ์ํค๋ ๋ฐฉ๋ฒ
public class ThreadSafe_Lazy_Initialization{ private volatile static ThreadSafe_Lazy_Initialization instance; private ThreadSafe_Lazy_Initialization(){} public static ThreadSafe_Lazy_Initialization getInstance(){ if(instance == null) { synchronized (ThreadSafe_Lazy_Initialization.class){ if(instance == null){ instance = new ThreadSafe_Lazy_Initialization(); } } } return instance; } }
1๋ฒ๊ณผ๋ ๋ฌ๋ฆฌ, ๋จผ์ ์กฐ๊ฑด๋ฌธ์ผ๋ก ์ธ์คํด์ค์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ ๋ค์ ๋๋ฒ์งธ ์กฐ๊ฑด๋ฌธ์์ synchronized๋ฅผ ํตํด ๋๊ธฐํ๋ฅผ ์์ผ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ
์ค๋ ๋๋ฅผ ์์ ํ๊ฒ ๋ง๋ค๋ฉด์, ์ฒ์ ์์ฑ ์ดํ์๋ synchronized๋ฅผ ์คํํ์ง ์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ํ ์ํ๊ฐ ๊ฐ๋ฅํจ
ํ์ง๋ง ์์ ํ ์๋ฒฝํ ๋ฐฉ๋ฒ์ ์๋
-
ํด๋์ค ์์ ํด๋์ค(holder)๋ฅผ ๋์ด JVM์ ํด๋์ค ๋ก๋ ๋งค์ปค๋์ฆ๊ณผ ํด๋์ค๊ฐ ๋ก๋๋๋ ์์ ์ ์ด์ฉํ ๋ฐฉ๋ฒ
public class Something { private Something() { } private static class LazyHolder { public static final Something INSTANCE = new Something(); } public static Something getInstance() { return LazyHolder.INSTANCE; } }
2๋ฒ์ฒ๋ผ ๋๊ธฐํ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๋ฐฉ๋ฒ์ ์ํ๋ ์ด์ ๋, ๊ฐ๋ฐ์๊ฐ ์ง์ ๋๊ธฐํ ๋ฌธ์ ์ ๋ํ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ํํผํ๋ ค๊ณ ํ๋ฉด ํ๋ก๊ทธ๋จ ๊ตฌ์กฐ๊ฐ ๊ทธ๋งํผ ๋ณต์กํด์ง๊ณ ๋น์ฉ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์. ๋ํ ์ฝ๋ ์์ฒด๊ฐ ์ ํํ์ง ๋ชปํ ๋๋ ๋ง์
์ด ๋๋ฌธ์, 3๋ฒ๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก JVM์ ํด๋์ค ์ด๊ธฐํ ๊ณผ์ ์์ ๋ณด์ฅ๋๋
์์์ ํน์ฑ
์ ์ด์ฉํด ์ฑ๊ธํค์ ์ด๊ธฐํ ๋ฌธ์ ์ ๋ํ ์ฑ ์์ JVM์๊ฒ ๋ ๋๊ธฐ๋ ๊ฑธ ํ์ฉํจ
ํด๋์ค ์์ ์ ์ธํ ํด๋์ค์ธ holder์์ ์ ์ธ๋ ์ธ์คํด์ค๋ static์ด๊ธฐ ๋๋ฌธ์ ํด๋์ค ๋ก๋ฉ์์ ์์ ํ๋ฒ๋ง ํธ์ถ๋๋ค. ๋ํ final์ ์ฌ์ฉํด์ ๋ค์ ๊ฐ์ด ํ ๋น๋์ง ์๋๋ก ๋ง๋๋ ๋ฐฉ์์ ์ฌ์ฉํ ๊ฒ
์ค์ ๋ก ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ์ผ๋ฐ์ ์ธ ์ฑ๊ธํค ํด๋์ค ์ฌ์ฉ ๋ฐฉ๋ฒ์ด 3๋ฒ์ด๋ค.