๊ฐœ๋ฐœ/Java

[Thread] ๋™์‹œ์„ฑ ์ด์Šˆ(Synchronization Issue), ์“ฐ๋ ˆ๋“œ๋กœ์ปฌ(ThreadLocal), ์“ฐ๋ ˆ๋“œํ’€(ThreadPool), ์“ฐ๋ ˆ๋“œ์— ์•ˆ์ „ํ•œ ์„ค๊ณ„(ThreadSafe)์— ๋Œ€ํ•œ ๊ณต๋ถ€ ๊ธฐ๋ก

daramii 2022. 4. 23. 21:54

๐Ÿ’ก๋™์‹œ์„ฑ ์ด์Šˆ๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

๋™์‹œ์„ฑ ์ด์Šˆ๋ž€ ์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ์‹ฑ๊ธ€ํ†ค(Singleton) ํŒจํ„ด์„ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

โœ…์‹ฑ๊ธ€ํ†ค(Singleton) ํŒจํ„ด์ด๋ž€?

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

 

์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

@Service 
public class UserService {
	
    private static UserId userId; // ์ƒํƒœ ๊ฐ’ 
    
    public void createUser(User user) {
    // ์—ฌ๊ธฐ์„œ userId ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์กด์žฌ 
    } 
}

 

UserService ๋Š” ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋กœ ๋“ฑ๋ก๋˜๋Š” ๋นˆ์ด๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ UserId๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒํƒœ ๊ฐ’์ธ๋ฐ, ํšŒ์› ๊ฐ€์ž… 100๊ฑด์ด ๋™์‹œ์— ์ด๋ฃจ์–ด์กŒ๋‹ค๊ณ  ํ•˜๋ฉด userId ๋ผ๋Š” ์ƒํƒœ๊ฐ’์€ ์•ˆ์ „ํ• ๊นŒ? ์•ˆ์ „ํ•˜์ง€ ์•Š์„๊นŒ? 

 

์“ฐ๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค์˜ Stack, Heap, Data, Text ์˜์—ญ ์ค‘ Stack ๋ถ€๋ถ„์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€๋ฅผ ๊ณต์œ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  userId ์˜ ์ƒํƒœ ๊ฐ’์€ ์ „์—ญ๋ณ€์ˆ˜์ด๋ฉฐ Process์˜ Data ์˜์—ญ์— ์ ์žฌ๋œ๋‹ค. ์ฆ‰, ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์ˆ˜ ๋งŽ์€ ์“ฐ๋ ˆ๋“œ๋“ค์ด userId ๋ผ๋Š” ์ƒํƒœ ๊ฐ’(์ „์—ญ ๋ณ€์ˆ˜)์„ ๊ณต์œ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๊ฒŒ๋˜๋ฉด, ํšŒ์› ๊ฐ€์ž…ํ›„์— ์„œ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ๊ฐœ์ธ์ •๋ณด๊ฐ€ ๋ณด์ธ๋‹ค๋Š” ๋“ฑ, ์‹ฌ๊ฐํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ์ ˆ๋Œ€ ์งœ๋ฉด ์•ˆ๋œ๋‹ค. ๋น„๋ก ํŠธ๋ž˜ํ”ฝ์ด ๋‚ฎ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ผ์ง€๋ผ๋„ ๋ง์ด๋‹ค.

 

๊ทธ๋Ÿฌ๋ฉด ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

 

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

 

๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ณณ์€ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ, ๋˜๋Š” static ๊ฐ™์€ ๊ณต์šฉ ํ•„๋“œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค. ๋™์‹œ์„ฑ ๋ฌธ์ œ๋Š” ๊ฐ’์„ ์ฝ๊ธฐ๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ , ์–ด๋””์„ ๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

 

 

๐Ÿ’กThreadLocal ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

ํ•˜์ง€๋งŒ, ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด์—์„œ ์ƒํƒœ ๊ฐ’์„ ๊ฐ€์ ธ์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ”ผํ• ๊นŒ?

์‹ฑ๊ธ€ํ†ค ๋นˆ์—์„œ ์ƒํƒœ๊ฐ’์„ ์œ ์ง€ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์— ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ThreadLocal์„ ์ง€์›ํ•œ๋‹ค.

ThreadLocal ์€ ํ•ด๋‹น ์“ฐ๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์ €์žฅ์†Œ(๋ณ„๋„์˜ ๋‚ด๋ถ€ ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณต)๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, ์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ƒํƒœ ๊ฐ’์— ์ ‘๊ทผํ•ด๋„ ๋™์‹œ์„ฑ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

์œ„ ์ฝ”๋“œ์— ThreadLocal ์„ ์ ์šฉํ•ด๋ณด์ž.

@Service
public class UserService {

    private static final ThreadLocal<UserId> userIdStore = new ThreadLocal<>(); 

    public void createUser(User user) {
        userIdStore.set(user.createUserId());
    }
    
     public static UserId get() {
        return userIdStore.get();
    }

    public static void remove() {
        userIdStore.remove();
    }
    
}

์œ„ ์ฒ˜๋Ÿผ ThreadLocal ์„ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฐ ์“ฐ๋ ˆ๋“œ๋Š” UserId ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์ž์‹ ๋งŒ์˜ ๋ณ„๋„์˜ ๋‚ด๋ถ€ ์ €์žฅ์†Œ์—์„œ ๊บผ๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ๋™์‹œ์„ฑ ์ด์Šˆ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋‹ค.

 

 

๐Ÿ’กThreadLocal์— ์ €์žฅ๋œ ๊ฐ’์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ• ๊นŒ?

ThreadLocal ์„ ์‚ฌ์šฉํ•  ๋•Œ์˜ ์ฃผ์˜์ ์€ ํ•ด๋‹น ์“ฐ๋ ˆ๋“œ๊ฐ€ ์“ฐ๋ ˆ๋“œ ๋กœ์ปฌ์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ณ  ๋‚˜๋ฉด ThreadLocal.remove() ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์“ฐ๋ ˆ๋“œ ๋กœ์ปฌ์— ์ €์žฅ๋œ ๊ฐ’์„ ์ œ๊ฑฐํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

์ œ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉด ํŠน์ • ์ƒํ™ฉ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜, ๊ฐœ์ธ์ •๋ณด ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ WAS ์ฒ˜๋Ÿผ ์“ฐ๋ ˆ๋“œ ํ’€(Thread Pool)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์“ฐ๋ ˆ๋“œ ํ’€์€ ์š”์ฒญ ๋งˆ๋‹ค ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ–ˆ์„ ๊ฒฝ์šฐ์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ๋‹ค๊ณ  ์œ„์—์„œ ๋ฐฐ์› ๋‹ค. ๋”ฐ๋ผ์„œ, WAS ๋Š” ์“ฐ๋ ˆ๋“œ ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด ํ•ด๋‹น ์“ฐ๋ ˆ๋“œ๋ฅผ ๋‹ค์‹œ ๋ฐ˜๋‚ฉํ•œ๋‹ค.

 

A ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์› ๊ฐ€์ž… ์š”์ฒญ์„ ํ•˜์—ฌ thread-A ๊ฐ€ ํ• ๋‹น๋˜์—ˆ๋‹ค. thread-A ๊ฐ€ ์‚ฌ์šฉ์ž์˜ A ์˜ ๋ฐ์ดํ„ฐ(User)๋ฅผ ์ž์‹ ์˜ ์ „์šฉ ๋ณด๊ด€์†Œ์ธ thread-A-privacy-storage ์— ์ €์žฅํ•œ๋‹ค. A ์˜ ์š”์ฒญ์ด ๋๋‚˜๊ณ ๋‚˜๋ฉด WAS ๋Š” ์‚ฌ์šฉ์ด ๋๋‚œ thread-A ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์“ฐ๋ ˆ๋“œ ํ’€์— ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, thread-A ๊ฐ€ ์ œ๊ฑฐ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ thread-A-privacy-storage ๋„ ์‚ด์•„์žˆ๊ฒŒ๋œ๋‹ค.

 

B ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ์„ ํ•œ๋‹ค. WAS ๋Š” ์“ฐ๋ ˆ๋“œ ํ’€์—์„œ ๋‚จ๋Š” ์“ฐ๋ ˆ๋“œ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๋Š”๋ฐ, ์ด๋•Œ ์–ด๋–ค ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ• ๋‹น๋ ์ง€๋Š” ๋ชจ๋ฅธ๋‹ค. thread-A ๊ฐ€ ํ• ๋‹น๋  ์ˆ˜๋„ ์žˆ๊ณ , ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ํ• ๋‹น๋  ์ˆ˜ ๋„ ์žˆ๋‹ค. thread-A ๊ฐ€ ํ• ๋‹น๋˜๋ฉด thread-A-privacy-storage ์— ๋“ค์–ด์žˆ๋˜ ์‚ฌ์šฉ์ž A ์— ๋Œ€ํ•œ ๊ฐœ์ธ์ •๋ณด๊ฐ€ ์กฐํšŒ๋œ๋‹ค. ๋”ฐ๋ผ์„œ, ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ๊ฐœ์ธ์ •๋ณด๊ฐ€๋…ธ์ถœ ๋˜๋Š” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋ ‡๊ฒŒ ๋•Œ๋ฌธ์— ThreadLocal ์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‚˜์„œ ThreadLocal.remove() ๋ฅผ ํ†ตํ•ด ์ž์‹ ์˜ ์ „์šฉ ๋ณด๊ด€์†Œ์— ์ €์žฅ๋˜์–ด ์žˆ๋˜ ๊ฐ’๋“ค์„ ๋ชจ๋‘ ์ œ๊ฑฐํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

โœ…์ •๋ฆฌ

- ThreadLocal์— ์ €์žฅ๋œ ๊ฐ’์€ ํ•ด๋‹น ์“ฐ๋ ˆ๋“œ์—์„œ ๊ณ ์œ ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
- ThreadLocal ํด๋ž˜์Šค์˜ ๋ณ€์ˆ˜๋Š” private static final๋กœ ์„ ์–ธํ•œ๋‹ค.
- ThreadLocal ํด๋ž˜์Šค์— ์„ ์–ธ๋˜์–ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋Š” set(), get(), remove(), initialValue()๊ฐ€ ์žˆ๋‹ค.
- ์‚ฌ์šฉ์ด ๋๋‚œ ํ›„์—๋Š” remove() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ์Šต๊ด€์„ ๊ฐ€์ ธ์•ผ๋งŒ ํ•œ๋‹ค.

 

์ฐธ๊ณ ๋กœ ์œ„์˜ ๋ฐ•์Šค์—์„œ 3๋ฒˆ์งธ๋ฅผ ๋ณด๋ฉด, initialValue()๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๊ฒƒ์€ ThreadLocal ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ• ๋•Œ, ์ด ๋ฉ”์†Œ๋“œ๋ฅผ Overrideํ•˜์—ฌ ์ดˆ๊ธฐ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ’ก์“ฐ๋ ˆ๋“œํ’€(ThreadPool)์€ ๋ฌด์—‡์ธ๊ฐ€?

์›น ๊ธฐ๋ฐ˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์“ฐ๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์“ฐ๋ ˆ๋“œ ํ’€(Thread Pool)์ด๋ผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•œ๋‹ค. 

 

WAS(Web Application Server)์˜ ์“ฐ๋ ˆ๋“œ ํ’€์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

1. ํ’€(Pool)์•ˆ์— ๋ฏธ๋ฆฌ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋†“๋Š”๋‹ค.
2. ์‚ฌ์šฉ์ž ์š”์ฒญ์ด ์˜ค๋ฉด ์“ฐ๋ ˆ๋“œ ํ’€์—๊ฒŒ ๋†€๊ณ  ์žˆ๋Š” ์“ฐ๋ ˆ๋“œ๋ฅผ ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•œ๋‹ค.
3. ์“ฐ๋ ˆ๋“œ ํ’€์—์„œ ์“ฐ๋ ˆ๋“œ๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ด๋‹ค.
4. ์“ฐ๋ ˆ๋“œ ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด ๋‹ค์‹œ ์“ฐ๋ ˆ๋“œ ํ’€์—๊ฒŒ ๋ฐ˜๋‚ฉ์„ ํ•œ๋‹ค.

์ฆ‰, ์“ฐ๋ ˆ๋“œ๋ฅผ ์“ฐ๋ ˆ๋“œ ํ’€์—์„œ ๋นŒ๋ ค ์“ฐ๊ณ , ๋‹ค์‹œ ๋ฐ˜๋‚ฉํ•˜๋Š” ์‹์ด๋‹ค. ์“ฐ๋ ˆ๋“œ ํ’€์•ˆ์— ์“ฐ๋ ˆ๋“œ๊ฐ€ 500 ๊ฐœ์ด๋ฉฐ, 500 ๊ฐœ๋ฅผ ๋„˜๋Š” ์š”์ฒญ์ด ์˜ค๋ฉด, ์“ฐ๋ ˆ๋“œ ๋Œ€๊ธฐ, ๊ฑฐ์ ˆ๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ์“ฐ๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ข…๋ฃŒํ•˜๋Š” ๋น„์šฉ(CPU)์ด ์ ˆ์•ฝ๋˜๊ณ , ์‘๋‹ต์‹œ๊ฐ„์ด ๋น ๋ฅด๋‹ค. ๋˜ํ•œ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•œ ์“ฐ๋ ˆ๋“œ์˜ ์ตœ๋Œ€์น˜๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ์ด ๋“ค์–ด์™€๋„ ๊ธฐ์กด ์š”์ฒญ์€ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ’ก๊ทธ๋ ‡๋‹ค๋ฉด Thread Safeํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ?

Thread Safe ๋ž€ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋™์‹œ์„ฑ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•˜๊ณ , OS ์ง€์‹๊ณผ ์„ž์–ด์„œ ํ’€์–ด ์„ค๋ช…ํ•˜๋ฉด, ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ฒฝ์Ÿ ์ƒํƒœ(race condition)์ผ ๋•Œ, ์ž„๊ณ„ ๊ตฌ์—ญ์— ์žˆ๋Š” ๊ณต์œ  ๋ณ€์ˆ˜์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€์‹œํ‚ค๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

1. java.util.concurrent ํŒจํ‚ค์ง€ ํ•˜์œ„์˜ ํด๋ž˜์Šค ์‚ฌ์šฉ ํ•˜๊ธฐ (Ex. ConcurrentHashMap ๋“ฑ)
2. ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๋‘์ง€ ์•Š๊ธฐ = ์ƒํƒœ ๊ฐ’ ๋‘์ง€ ์•Š๊ธฐ
3. Thread-safeํ•œ singleton ํŒจํ„ด ์‚ฌ์šฉํ•˜๊ธฐ (Ex. LazyHolder ๋“ฑ)
4. ๋™๊ธฐํ™” ๋ธ”๋Ÿญ(synchronized) ์ง€์ •ํ•˜๊ธฐ

 

ํŠนํžˆ 3๋ฒˆ์— ํ•ด๋‹นํ•˜๋Š” ์ด์•ผ๊ธฐ๋Š” ํ•  ์ด์•ผ๊ธฐ๊ฐ€ ๋งŽ๊ณ , ์ƒˆ๋กœ์šด ๊ฐœ๋…๋“ค์ด ๋‚˜์˜ค๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์€ ๋‹ค์Œ ๊ธ€์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค :)

 

 

๐Ÿ“—Reference

- ์ž๋ฐ”์˜ ์‹ 
- https://techvu.dev/87
- https://cjw-awdsd.tistory.com/42