๋™์‹œ์„ฑ(Concurrency)

โ€œObjects are abstractions of processing. Threads are abstractions of schedule.โ€ โ€” James O. Coplien

Thread๋ฅผ ํ•˜๋‚˜๋งŒ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋Š” ์งœ๊ธฐ๊ฐ€ ์‰ฝ๋‹ค. ๊ฒ‰์œผ๋กœ ๋ณด๊ธฐ์—๋Š” ๋ฉ€์ฉกํ•˜์ง€๋งŒ ๊นŠ์ˆ™ํ•œ ๊ณณ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๋‹ค์ค‘ Thread ์ฝ”๋“œ๋„ ์งœ๊ธฐ ์‰ฝ๋‹ค. ์‹œ์Šคํ…œ์ด ์ปค์ง€๊ณ  ๋ถ€ํ•˜๊ฐ€ ์ปค์ง€๋ฉด ๋ฌธ์ œ๋Š” ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ง€ํ‚ค๋Š” ๊ทœ์น™์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•œ๋‹ค.

์™œ Concurrency๊ฐ€ ํ•„์š”ํ•œ๊ฐ€?

Concurrency๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ ์—ฎ์—ฌ ์žˆ๋˜ โ€œ๋ฌด์—‡(What)์„ ํ•  ๊ฒƒ์ธ๊ฐ€โ€์™€ โ€œ์–ธ์ œ(When) ๋๋‚  ๊ฒƒ์ธ๊ฐ€โ€๊ฐ„์˜ Coupoing์„ ํ•ด์†Œ์‹œ์ผœ ์ค€๋‹ค. ์ด๋Š” ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ๊ตฌ์กฐ ๊ฐœ์„ ์— ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ๊ฑฐ๋Œ€ํ•œ ํ•˜๋‚˜์˜ Loop๊ฐ€ ์•„๋‹ˆ๋ผ ์ž‘์€ ํ˜‘๋ ฅ ํ”„๋กœ๊ทธ๋žจ ์—ฌ๋Ÿฟ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์‰ฝ๋‹ค.

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

๋ฏธ์‹ ๊ณผ ์˜คํ•ด

Concurrency๋Š” ํ•ญ์ƒ ํผํฌ๋จผ์Šค๋ฅผ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๊ฒƒ๋งŒ์€ ์•„๋‹ˆ๋‹ค. Concurrency๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ํ˜น์€ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์„œ๊ฐ€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ํผํฌ๋จผ์Šค๋ฅผ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ๋‹ค. ๋˜ํ•œ Context Switching์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ํผํฌ๋จผ์Šค, ์ฝ”๋“œ ์ž‘์„ฑ ์–‘์ชฝ ๋ชจ๋‘์— ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ผ์œผํ‚จ๋‹ค.

Concurrency๋Š” ์‹œ์Šคํ…œ์˜ ๋””์ž์ธ์„ ๋ณ€๊ฒฝ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

โ€œ๋ฌด์—‡โ€๊ณผ โ€œ์–ธ์ œโ€๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์ž‘์—…์€ ๋ณดํ†ต ์‹œ์Šคํ…œ์˜ ๊ตฌ์กฐ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค. Concurrency ๋ฌธ์ œ์—๋Š” ๋ณดํ†ต ๊ทผ๋ณธ์ ์ธ ๋””์ž์ธ ๊ฐœํŽธ์ด ํ•„์š”ํ•˜๋‹ค.

Web๋‚˜ EJB์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด Concurrency ๋ฌธ์ œ๋“ค์€ ์‹ ๊ฒฝ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค.

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์–ด๋–ค ์ผ์„ ํ•˜๋Š”๊ฐ€์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•˜๋ฉฐ Concurrency update, Deadlock์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.

Concurrency ๊ด€๋ จ ๋ฒ„๊ทธ๋Š” ์žฌํ˜„ํ•˜๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์ข…์ข… one-off 2๋กœ ์ทจ๊ธ‰๋œ๋‹ค.

์™œ Concurrency๋Š” ๊ตฌํ˜„ํ•˜๊ธฐ ์–ด๋ ค์šด๊ฐ€?

public class ClassWithThreadingProblem {
    private int lastIdUsed;
 
    public ClassWithThreadingProblem(int lastIdUsed) {
        this.lastIdUsed = lastIdUsed;
    }
 
    public int getNextId() {
        return ++lastIdUsed;
    }
 
    public static void main(String args[]) {
        final ClassWithThreadingProblem classWithThreadingProblem = new ClassWithThreadingProblem(42);
 
        Runnable runnable = new Runnable() {
            public void run() {
                classWithThreadingProblem.getNextId();
            }
        };
 
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
    }
}

๊ฒฐ๊ณผ๋Š” ์ด 3๊ฐ€์ง€ ์ด๋‹ค.

  • t1์ด 43์„, t2๊ฐ€ 44๋ฅผ ๊ฐ€์ ธ๊ฐ„๋‹ค. lastIdUsed๋Š” 44์ด๋‹ค.(O)
  • t1์ด 44์„, t2๊ฐ€ 43๋ฅผ ๊ฐ€์ ธ๊ฐ„๋‹ค. lastIdUsed๋Š” 44์ด๋‹ค.(O)
  • t1์ด 43์„, t2๊ฐ€ 43๋ฅผ ๊ฐ€์ ธ๊ฐ„๋‹ค. lastIdUsed๋Š” 43์ด๋‹ค.(X)

์œ„์˜ getNextId() ๋ฉ”์„œ๋“œ๋Š” 8๊ฐœ์˜ ์ž๋ฐ” byte-code๋กœ ๋ณ€ํ™˜๋˜๋ฉฐ, ์ด๋ฅผ ๋‘ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ์ด 12,870๊ฐœ์˜ ์ฝ”๋“œ ์กฐํ•ฉ์„ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ์ค‘ ์–ผ๋งˆ ์•ˆ ๋˜๋Š” ๋ช‡๋ช‡ ์กฐํ•ฉ์ด ์œ„์˜ 3๊ฐ€์ง€ ๊ฒฐ๊ณผ ์ค‘ ๋งˆ์ง€๋ง‰ ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ๊ฒŒ ๋œ๋‹ค.

๋™์‹œ์„ฑ ๋ฐฉ์–ด ์›์น™

๋‹จ์ผ ์ฑ…์ž„ ์›์น™(Single Responsibility Principle, SRP)

Concurrency ๋””์ž์ธ์€ ๊ทธ ์ž์ฒด๋กœ ์ถฉ๋ถ„ํžˆ ๋ณต์žกํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ concurrency ๊ด€๋ จ ์ฝ”๋“œ๋Š” ๋ถ„๋ฆฌ๋˜์–ด์•ผ ํ•œ๋‹ค.

  • Concurrency ๊ด€๋ จ ์ฝ”๋“œ๋Š” ๊ฐœ๋ฐœ, ๋ณ€๊ฒฝ, ํŠœ๋‹์‹œ ๋‹ค๋ฅธ ์ฝ”๋“œ์™€ ๋ถ„๋ฆฌ๋œ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„๋‹ค.
  • Concurrency ๊ด€๋ จ ์ฝ”๋“œ๋Š” ๊ทธ ์ž์ฒด๊ฐ€ ๊ฐ€์ง€๋Š” ์–ด๋ ค์›€(ํ’€๊ธฐ ํž˜๋“  ๋ฌธ์ œ)์ด ์žˆ๋‹ค.
  • ์ž˜๋ชป ์ž‘์„ฑ๋œ concurrency ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ ์—†์ด ํ•ด๊ฒฐ๋˜๊ธฐ ํž˜๋“ค๋‹ค.

Concurrency ๊ด€๋ จ ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค๊ณผ ๋ถ„๋ฆฌํ•˜๋ผ.

๋”ฐ๋ฆ„ ์ •๋ฆฌ(Corollary): ์ž๋ฃŒ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๋ผ

๊ณต์œ  ๊ฐ์ฒด๋ฅผ ๋‘ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜์ •ํ•˜๋Š” ์ค‘ ๊ฐ„์„ญ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋Š” ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ critical section์„ ๋ณดํ˜ธํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Critical section์˜ ์ˆ˜๋Š” ๊ฐ€๋Šฅํ•œํ•œ ์ ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฉฐ ์ด๋ฅผ ์–ด๊ธธ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋œ๋‹ค.

  • ํ•œ๋‘ ๊ตฐ๋ฐ๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๊ฒƒ์„ ๊นŒ๋จน๊ธฐ ์‰ฌ์šฐ๋ฉฐ ์ด๋กœ ์ธํ•ด ํ•ด๋‹น ์ž์›์„ ์ˆ˜์ •ํ•˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋ง๊ฐ€ํŠธ๋ฆฌ๊ฒŒ ๋œ๋‹ค.
  • ๋ชจ๋“  ๊ณณ์ด ๋ณดํ˜ธ๋˜์—ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์ค‘๋ณต์ ์ธ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ด๋ฏธ ์ฐพ๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ์˜ ๊ทผ์›์„ ๋” ์ฐพ๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.

๋ฐ์ดํ„ฐ ์บก์Šํ™”๋ฅผ ๊ฐ€์Šด ๊นŠ์ด ์ƒˆ๊ธฐ๋ฉฐ, ๊ณต์œ ๋  ๋งŒํ•œ ์ž์›์— ์ ‘๊ทผํ•˜๋Š” ๋ถ€๋ถ„(์ฝ”๋“œ)์„ ๊ทน๋„๋กœ ์ค„์—ฌ๋ผ.

๋”ฐ๋ฆ„ ์ •๋ฆฌ: ์ž๋ฃŒ ์‚ฌ๋ณธ์„ ์‚ฌ์šฉํ•˜๋ผ

  • ๊ณต์œ  ์ž์› ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜๋Š” ์• ์ดˆ์— ๊ณต์œ  ์ž์›์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.
  • ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์‚ฌ์šฉ๋  ๊ฒฝ์šฐ ์ž์›์˜ ๋ณต์‚ฌ๋ณธ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ๋Š” ๋ณต์‚ฌ๋ณธ์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์— ์ „๋‹ฌ, ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜์ง‘ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ฐ์ฒด์˜ ๋ณต์‚ฌ์— ๋“œ๋Š” ๋น„์šฉ์„ ๊ฑฑ์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋™๊ธฐํ™”๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ GC์— ๋“œ๋Š” ๋น„์šฉ์€ ๊ณต์œ  ์ž์› ๋™๊ธฐํ™”์— ํ•„์š”ํ•œ ๋น„์šฉ ๋ณด๋‹ค ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์€ ๋น„์šฉ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ฒŒ ํ•ด ์ค€๋‹ค.(๊ฐ์ฒด ๋ณต์‚ฌ cost < ๊ณต์œ  ์ž์› ๋™๊ธฐํ™” cost)

๋”ฐ๋ฆ„ ์ •๋ฆฌ: ์Šค๋ ˆ๋“œ๋Š” ๊ฐ€๋Šฅํ•œ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ผ

  • ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ  ์ž์›์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋…๋ฆฝ๋œ ์„ธ๊ณ„๋กœ ๋งŒ๋“ ๋‹ค๋ฉด ๋™๊ธฐํ™” ๋ฌธ์ œ๋Š” ์—†์–ด์ง€๊ฒŒ ๋œ๋‹ค. HttpServlet์„ ์ƒ๊ฐํ•ด ๋ณด๋ผ. HttpServlet์„ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค๋Š” doGet, doPost์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ์—์„œ ํ•„์š”ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ด๋Š” ๊ฐ Servlet์ด ๊ฐ์ž์˜ ์„ธ๊ณ„์— ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๊ฒŒ ๋„์™€์ฃผ๋ฉฐ, ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•œ ๋™๊ธฐํ™” ๋ฌธ์ œ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ๋ฌผ๋ก  ๋Œ€๋ถ€๋ถ„์˜ Servlet๋“ค์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ๊ณผ ๊ฐ™์€ ๊ณต์œ  ์ž์›์ด ํ•„์š”ํ•˜๊ธด ํ•˜๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ์Šค๋ ˆ๋“œ ๋” ๋‚˜์•„๊ฐ€ ๊ฐ๊ฐ์˜ ํ”„๋กœ์„ธ์„œ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๊ฒŒ ๋…๋ฆฝ์ ์ธ ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•˜๋ผ.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ดํ•ดํ•˜๊ธฐ

  • ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” thread-safe ์ปฌ๋ž™์…˜์„ ์‚ฌ์šฉํ•˜๋ผ. ex) ConCurrentHashMap, Vector
  • ์—ฐ๊ด€์ด ์—†๋Š” ํƒœ์Šคํฌ๋“ค์„ ์ˆ˜ํ–‰์‹œ executor ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.
  • ๊ฐ€๋Šฅํ•˜๋ฉด nonblocking ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ผ.
  • ๋ช‡๋ช‡ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํด๋ž˜์Šค๋“ค์€ thread-safeํ•˜์ง€ ์•Š๋‹ค.

Thread Safe ์ปฌ๋ ‰์…˜

java.util.concurrent ํŒจํ‚ค์ง€๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปฌ๋ž™์…˜๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. ConcurrentHashMap์˜ ๊ฒฝ์šฐ์—๋Š” ์ผ๋ฐ˜ HashMap๋ณด๋‹ค ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ์—์„œ ๋” ์ข‹์€ ํผํฌ๋จผ์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋งŒ์•ฝ ๋ฐฐํฌ ํ™˜๊ฒฝ์ด ์ž๋ฐ” 5๋ฒ„์ „ ์ด์ƒ์ด๋ผ๋ฉด ์ด ํŒจํ‚ค์ง€๋ฅผ ํ™œ์šฉํ•˜์ž. ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณ ๊ธ‰ concurrency ๋””์ž์ธ ๊ตฌํ˜„์„ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค๋„ ์ˆ™์ง€ํ•˜์ž.

NameDescription
ReentrantLockํ•œ ๋ฉ”์„œ๋“œ์—์„œ ์ž ๊ทธ๊ณ  ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์—์„œ ํ•ด์ œ๋  ์ˆ˜ ์žˆ๋Š” lock์ด๋‹ค.
Semaphore์ „ํ†ต์ ์ธ ์„ธ๋งˆํฌ์–ด(๊ฐฏ์ˆ˜๋ฅผ ์…€ ์ˆ˜ ์žˆ๋Š” lock)์˜ ๊ตฌํ˜„์ฒด์ด๋‹ค.
CountDownLatch๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋“ค์„ ํ•ด์ œํ•˜๊ธฐ ์ „ ํŠน์ • ํšŸ์ˆ˜์˜ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” lock์ด๋‹ค. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฑฐ์˜ ๋™์‹œ์— ์‹œ์ž‘๋  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค„ ์ˆ˜ ์žˆ๋‹ค.

๋‹น์‹ ์—๊ฒŒ ๋งž๋Š” ํด๋ž˜์Šค๋ฅผ ์‚ดํŽด๋ณด๋ผ. ์ž๋ฐ”์˜ ๊ฒฝ์šฐ java.util.concurrent, java.util.concurrent.atomic, java.util.concurrent.locks๋ฅผ ์‚ดํŽด๋ณด๋ผ.

์‹คํ–‰ ๋ชจ๋ธ ์ดํ•ดํ•˜๊ธฐ

NameDescription
ํ•œ์ •๋œ ์ž์›(Bound Resource)๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ž์›์œผ๋กœ ํฌ๊ธฐ๋‚˜ ์ˆซ์ž๊ฐ€ ์ œํ•œ์ ์ด๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ, ๊ธธ์ด๊ฐ€ ์ผ์ •ํ•œ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ฒ„ํผ ๋“ฑ์ด ์˜ˆ๋‹ค.
์ƒํ˜ธ ๋ฐฐ์ œ(Mutual Exclusion)ํ•œ ๋ฒˆ์— ํ•œ ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ์ž๋ฃŒ๋‚˜ ๊ณต์œ  ์ž์›์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
๊ธฐ์•„(Starvation)ํ•œ ์Šค๋ ˆ๋“œ๋‚˜ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ต‰์žฅํžˆ ์˜ค๋žซ๋™์•ˆ ํ˜น์€ ์˜์›ํžˆ ์ž์›์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
๋ฐ๋“œ๋ฝ(Deadlock)์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์„œ๋กœ๊ฐ€ ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ๊ธฐ ํ•„์š”ํ•œ ์ž์›์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ์œ ํ•˜๋Š” ๋ฐ”๋žŒ์— ์–ด๋Š ์ชฝ๋„ ๋” ์ด์ƒ ์ง„ํ–‰ํ•˜์ง€ ๋ชปํ•œ๋‹ค.
๋ผ์ด๋ธŒ๋ฝ(Livelock)๋ฝ์„ ๊ฑฐ๋“  ๋‹จ๊ณ„์—์„œ ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์„œ๋กœ๋ฅผ ๋ฐฉํ•ดํ•œ๋‹ค.

์ƒ์‚ฐ์ž - ์†Œ๋น„์ž(Produce-Consumer)

ํ•œ ๊ฐœ ์ด์ƒ์˜ ์ƒ์‚ฐ์ž๊ฐ€ ์ƒ์‚ฐํ•œ ์ž‘์—…๋ฌผ์„ ๋ฒ„ํผ ํ˜น์€ ํ์— ๋„ฃ๋Š”๋‹ค. ํ•œ ๊ฐœ ์ด์ƒ์˜ ์†Œ๋น„์ž๊ฐ€ ๋ฒ„ํผ ํ˜น์€ ํ์—์„œ ์ž‘์—…๋ฌผ์„ ์Šต๋“, ์ž‘์—…์„ ๋งˆ์นœ๋‹ค. ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž ์‚ฌ์ด์— ์žˆ๋Š” ํ๋Š” bound resource์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์‚ฐ์ž๋Š” ํ์— ๋‚จ๋Š” ๊ณต๊ฐ„์ด ์ƒ๊ธธ ๋•Œ๊นŒ์ง€, ์†Œ๋น„์ž๋Š” ํ์— ์ž‘์—…๋ฌผ์ด ํ•˜๋‚˜๋ผ๋„ ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. ํ๋ฅผ ํ†ตํ•œ ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž๊ฐ„์˜ ์กฐ์œจ์—๋Š” ๋‘˜ ์‚ฌ์ด์˜ ์‹œ๊ทธ๋„๋ง์ด ํ•„์š”ํ•˜๋‹ค. ์ƒ์‚ฐ์ž๋Š” ํ์— ์ž‘์—…๋ฌผ์„ ๋„ฃ๊ณ  ์†Œ๋น„์ž์—๊ฒŒ โ€œํ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š๋‹คโ€๋Š” ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ด๊ณ  ์†Œ๋น„์ž๋Š” ํ์—์„œ ์ž‘์—…๋ฌผ์„ ๊บผ๋‚ธ ํ›„ โ€œํ๊ฐ€ ๊ฐ€๋“์ฐจ ์žˆ์ง€ ์•Š๋‹คโ€๋Š” ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ธ๋‹ค. ๊ทธ ์ „๊นŒ์ง€ ๋‘˜์€ ์‹ ํ˜ธ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

์ฝ๊ธฐ-์“ฐ๊ธฐ(Readers-Writers)

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

์‹์‚ฌํ•˜๋Š” ์ฒ ํ•™์ž๋“ค(Dining Philosophers)

์›ํƒ์„ ๋‘˜๋Ÿฌ์‹ผ ์—ฌ๋Ÿฌ ๋ช…์˜ ์ฒ ํ•™์ž๋“ค์ด ์žˆ๋‹ค. ๊ฐ ์ฒ ํ•™์ž์˜ ์™ผ์ชฝ์— ํฌํฌ๊ฐ€ ๋†“์—ฌ ์žˆ์œผ๋ฉฐ ํ…Œ์ด๋ธ”์˜ ์ค‘์•™์— ํฐ ์ŠคํŒŒ๊ฒŒํ‹ฐ ํ•œ ๊ทธ๋ฆ‡์ด ๋†“์—ฌ ์žˆ๋‹ค. ๊ทธ๋“ค์€ ๋ฐฐ๊ฐ€ ๊ณ ํŒŒ์ง€๊ธฐ ์ „๊นŒ์ง€ ๊ฐ์ž ์ƒ๊ฐ์„ ํ•˜๋ฉฐ ์‹œ๊ฐ„์„ ๋ณด๋‚ธ๋‹ค. ๋ฐฐ๊ฐ€ ๊ณ ํŒŒ์ง€๋ฉด ๊ทธ๋“ค์€ ์ž์‹ ์˜ ์–‘์ชฝ์— ๋†“์—ฌ ์žˆ๋Š” ํฌํฌ 2๊ฐœ๋ฅผ ์žก๊ณ  ์ŠคํŒŒ๊ฒŒํ‹ฐ๋ฅผ ๋จน๋Š”๋‹ค. ์ฒ ํ•™์ž๋Š” ํฌํฌ 2๊ฐœ๊ฐ€ ์žˆ์–ด์•ผ๋งŒ ์ŠคํŒŒ๊ฒŒํ‹ฐ๋ฅผ ๋จน์„ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ์˜† ์‚ฌ๋žŒ์ด ํฌํฌ๋ฅผ ๋‹ค ์‚ฌ์šฉํ•˜๊ธฐ ์ „๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. ์ŠคํŒŒ๊ฒŒํ‹ฐ๋ฅผ ๋จน์€ ์ฒ ํ•™์ž๋Š” ๋‹ค์‹œ ๋ฐฐ๊ฐ€ ๊ณ ํŒŒ์งˆ ๋•Œ๊นŒ์ง€ ํฌํฌ๋ฅผ ๋†“๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ์œ„ ์ƒํ™ฉ์—์„œ ์ฒ ํ•™์ž๋ฅผ ์Šค๋ ˆ๋“œ๋กœ, ํฌํฌ๋ฅผ ๊ณต์œ  ์ž์›์œผ๋กœ ๋ฐ”๊พธ๊ฒŒ ๋˜๋ฉด ์ด๋Š” ์ž์›์„ ๋†“๊ณ  ๊ฒฝ์Ÿํ•˜๋Š” ํ”„๋กœ์„ธ์Šค์™€ ๋น„์Šทํ•œ ์ƒํ™ฉ์ด ๋œ๋‹ค. ์ž˜ ์„ค๊ณ„๋˜์ง€ ์•Š์€ ์‹œ์Šคํ…œ์€ deadlock, livelock, ์ฒ˜๋ฆฌ๋Ÿ‰ ๋ฌธ์ œ, ํšจ์œจ์„ฑ ์ €ํ•˜ ๋ฌธ์ œ์— ๋งž๋‹ฅ๋œจ๋ฆฌ๊ธฐ ์‰ฝ๋‹ค. ๋‹น์‹ ์ด ๋งž๋‹ฅ๋œจ๋ฆด ๋Œ€๋ถ€๋ถ„์˜ concurrent๊ด€๋ จ ๋ฌธ์ œ๋“ค์€ ์ด ์„ธ ๊ฐ€์ง€ ๋ฌธ์ œ์˜ ๋ณ€ํ˜•์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค์„ ๊ณต๋ถ€ํ•˜๊ณ  ์Šค์Šค๋กœ ํ•ด๋ฒ•์„ ์ž‘์„ฑํ•จ์œผ๋กœ์จ ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์„ ์ง๋ฉดํ•˜๋”๋ผ๋„ ์˜์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.

๋™๊ธฐํ™”ํ•˜๋Š” ๋ฉ”์„œ๋“œ ์‚ฌ์ด์— ์กด์žฌํ•˜๋Š” ์˜์กด์„ฑ์„ ์ดํ•ดํ•˜๋ผ.

๋™๊ธฐํ™”๋œ ๋ฉ”์„œ๋“œ ๊ฐ„์˜ ์˜์กด์„ฑ์€ concurrent ์ฝ”๋“œ์—์„œ ์‚ฌ์†Œํ•œ ๋ฒ„๊ทธ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”๋Š” synchronized๋ผ๋Š” โ€œ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๋…ธํ…Œ์ด์…˜โ€์„ ์ œ๊ณตํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ํด๋ž˜์Šค์— ๋‘ ๊ฐœ ์ด์ƒ์˜ synchronized ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

์ถ”์ฒœ: ๊ณต์œ ๋œ ๊ฐ์ฒด์˜ ๋‘ ๋ฉ”์„œ๋“œ ์ด์ƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๋ผ.

๋งŒ์•ฝ ์œ„ ์ถ”์ฒœ์„ ๋”ฐ๋ฅผ ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์•„๋ž˜์˜ ์„ธ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด ๋ณด๋ผ.

ํด๋ผ์ด์–ธํŠธ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ(Client-Based Locking)

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฒซ ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ€๋ฅด๊ธฐ ์ด์ „๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ€๋ฅธ ๋‹ค์Œ๊นŒ์ง€ ์„œ๋ฒ„๋ฅผ ์ž ๊ทผ๋‹ค.

Bad: ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ lock์ด ํ•„์š”ํ•˜๊ฒŒ ๋˜๋ฉฐ ์ด๋Š” ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ๋””๋ฒ„๊น…์— ํ•„์š”ํ•œ ๋น„์šฉ์„ ์ƒ์Šน์‹œํ‚จ๋‹ค.

์„œ๋ฒ„ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ(Server-Based Locking)

  • ์„œ๋ฒ„ ๋‚ด์—์„œ ์„œ๋ฒ„(์ž์‹ )์„ ์ž ๊ทธ๊ณ  ๋ชจ๋“  ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ ํ›„ ์ž ๊ธˆ์„ ํ‘ธ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

Good: Critical section์— ์ ‘๊ทผํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ตœ์†Œํ™”ํ•ด ์œ„ 4-2์— ๋ถ€ํ•ฉํ•œ๋‹ค.

์ค‘๊ณ„๋œ ์„œ๋ฒ„(Adapted Server)

  • ์ž ๊ธˆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ค‘๊ณ„์ž๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. ์ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ์ด์ง€๋งŒ ๊ธฐ์กด์˜ ์„œ๋ฒ„๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

Good: ์„œ๋ฒ„ ๊ธฐ๋ฐ˜ ์ž ๊ธˆ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜์ž.

๋™๊ธฐํ™”ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ตœ๋Œ€ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ

  • Synchronized๋กœ ์ˆ˜ํ–‰๋˜๋Š” ์ž ๊ธˆ์€ ๋”œ๋ ˆ์ด์™€ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— โ€œ๋น„์‹ผ ์ˆ˜ํ–‰โ€์œผ๋กœ ๊ฐ„์ฃผ๋˜๋ฉฐ ๊ฐ€๋Šฅํ•œ ํ•œ ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๋ฐ˜๋ฉด critical section์€ ๊ผญ ๋ณดํ˜ธ๋˜์–ด์•ผ ํ•œ๋‹ค.

์˜ฌ๋ฐ”๋ฅธ ์ข…๋ฃŒ ์ฝ”๋“œ๋Š” ๊ตฌํ˜„ํ•˜๊ธฐ ์–ด๋ ต๋‹ค

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

์ถ”์ฒœ: ๊ฐœ๋ฐœ ์ดˆ๊ธฐ์— ์‹œ์Šคํ…œ ์ข…๋ฃŒ์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•˜๊ณ  ๊ตฌํ˜„ํ•˜๋ผ. ์ด ์ž‘์—…์€ ์ƒ๊ฐ๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ์ด๋‹ค. ๊ธฐ์กด์— ๊ตฌํ˜„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฆฌ๋ทฐํ•˜๋Š” ๊ฒƒ๋„ ํ•„์š”ํ•˜๋‹ค.

์Šค๋ ˆ๋“œ ์ฝ”๋“œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ

  • ํ…Œ์ŠคํŠธ๋Š” ์ •ํ™•์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ โ€œ์ฝ”๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘์„ฑ๋˜์—ˆ๋Š”๊ฐ€โ€๋ฅผ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†๋‹ค. ๋‹ค๋งŒ ์ž˜ ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ๋Š” ์œ„ํ—˜์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์ƒํ™ฉ์—์„œ๋Š” ํ›จ์”ฌ ๋” ๋ณต์žกํ•ด ์ง„๋‹ค.

์ถ”์ฒœ: ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๋งŒํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ ์„ค์ •๊ณผ ์‹œ์Šคํ…œ ์„ค์ •, ๋ถ€ํ•˜ ํ•˜์—์„œ ์ž์ฃผ ์ˆ˜ํ–‰ํ•˜๋ผ. ํ…Œ์ŠคํŠธ๊ฐ€ ํ•œ๋ฒˆ์ด๋ผ๋„ ์‹คํŒจํ•œ๋‹ค๋ฉด ์›์ธ์„ ๋ถ„์„ํ•˜๋ผ. ํ•œ๋ฒˆ ๋” ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด ์„ฑ๊ณตํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ์ด์ „์˜ ์‹คํŒจ๋ฅผ ๋ฌด์‹œํ•˜์ง€ ๋งˆ๋ผ.

  • ๋ง์ด ์•ˆ ๋˜๋Š” ์‹คํŒจ๋Š” ์ž ์ •์ ์ธ ์Šค๋ ˆ๋“œ ๋ฌธ์ œ๋กœ ์ทจ๊ธ‰ํ•˜๋ผ
  • ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์€ ์ˆœ์ฐจ ์ฝ”๋“œ๋ถ€ํ„ฐ ์ œ๋Œ€๋กœ ๋Œ๊ฒŒ ๋งŒ๋“ค์ž
  • ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ์“ฐ๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์— ์‰ฝ๊ฒŒ ๋ผ์›Œ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ผ
  • ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ์“ฐ๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์กฐ์œจํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑํ•˜๋ผ
  • ํ”„๋กœ์„ธ์„œ ์ˆ˜๋ณด๋‹ค ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ๋ ค๋ณด๋ผ
  • ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ ๋Œ๋ ค๋ณด๋ผ
  • ์ฝ”๋“œ์— ๋ณด์กฐ ์ฝ”๋“œinstrument๋ฅผ ๋„ฃ์–ด ๋Œ๋ ค๋ผ. ๊ฐ•์ œ๋กœ ์‹คํŒจ๋ฅผ ์ผ์œผํ‚ค๊ฒŒ ํ•ด๋ณด๋ผ

๋ง์ด ์•ˆ ๋˜๋Š” ์‹คํŒจ๋Š” ์ž ์ •์ ์ธ ์Šค๋ ˆ๋“œ ๋ฌธ์ œ๋กœ ์ทจ๊ธ‰ํ•˜๋ผ

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐœ์ƒํ•  ๋ฆฌ ์—†์–ด ๋ณด์ด๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. (์ €์ž๋ฅผ ํฌํ•จํ•œ)๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ํŒŒ์•…ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๋˜ํ•œ ์ด๋Š” ๋งค์šฐ ๋“œ๋ฌผ๊ฒŒ ๋ฐœ์ƒํ•ด ๊ฐœ๋ฐœ์ž๋“ค์„ ์ขŒ์ ˆํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ์šฐ์ฃผ์„ (ๅฎ‡ๅฎ™็ทš), ํ•˜๋“œ์›จ์–ด ๋ฒ„๊ทธ, ํ˜น์€ ์ด๋Ÿฌํ•œ ๋ฅ˜์˜ one-off๋กœ ์น˜๋ถ€ํ•œ๋‹ค. ์ œ์ผ ์ข‹์€ ๋ฐฉํ–ฅ์€ one-off๋Š” ์—†๋‹ค๊ณ  ํŒ๋‹จํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•œ one-off๋“ค์ด ๋ฌด์‹œ๋  ์ˆ˜๋ก ๋” ๋งŽ์€ ์ฝ”๋“œ๋“ค์ด ์ด๋ฏธ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์‹œ์Šคํ…œ์— ์ถ”๊ฐ€๋˜๊ฒŒ ๋  ๋ฟ์ด๋‹ค.

์ถ”์ฒœ: ์‹œ์Šคํ…œ ์˜ค์ž‘๋™์„ one-off๋กœ ํŒ๋‹จํ•ด ๋ฌด์‹œํ•˜์ง€ ๋ง๋ผ.

๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์€ ์ˆœ์ฐจ ์ฝ”๋“œ๋ถ€ํ„ฐ ์ œ๋Œ€๋กœ ๋Œ๊ฒŒ ๋งŒ๋“ค์ž

๋‹น์—ฐํ•œ ๋ง์ด์ง€๋งŒ ๊ฑฐ๋“ญ ๊ฐ•์กฐํ•  ๋งŒํผ ์ค‘์š”ํ•œ ์ด์•ผ๊ธฐ์ด๋‹ค. ์Šค๋ ˆ๋“œ ๋ฐ–์—์„œ ์ž˜ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•˜๋ผ. ์ด๋Š” ์Šค๋ ˆ๋“œ์—์„œ ์‚ฌ์šฉ๋  POJO๋ฅผ ๋œปํ•œ๋‹ค. POJO๋Š” ์Šค๋ ˆ๋“œ์™€ ์—ฐ๊ด€์ด ์—†์–ด ์Šค๋ ˆ๋“œ ๋ฐ–์—์„œ๋„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹œ์Šคํ…œ์€ ๊ฐ€๋Šฅํ•œ ํ•œ POJO๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์ถ”์ฒœ: ์Šค๋ ˆ๋“œ ๊ด€๋ จ ๋ฒ„๊ทธ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ฒ„๊ทธ๋ฅผ ๋™์‹œ์— ์žก์œผ๋ ค ํ•˜์ง€ ๋งˆ๋ผ. ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์Šค๋ ˆ๋“œ ๋ฐ–์—์„œ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ๋จผ์ € ์ฒดํฌํ•˜๋ผ.

๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ์“ฐ๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์— ์‰ฝ๊ฒŒ ๋ผ์›Œ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ผ

Concurrency ์ง€์› ์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ ์„ค์ •์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด๋ผ. ๋‹จ์ผ ์Šค๋ ˆ๋“œ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ๊ตฌํ˜„ ์‹ค์ œ ์‚ฌ์šฉ๋  ๊ฐ์ฒด ํ˜น์€ Test Double๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ ์ˆ˜ํ–‰ ์†๋„๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” Test Double์„ ๊ตฌํ˜„ ์ง€์ •๋œ ํšŸ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌํ˜„

์ถ”์ฒœ: ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜ ์ฝ”๋“œ๋ฅผ ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ผ.

๋‹ค์ค‘ ์Šค๋ ˆ๋“œ๋ฅผ ์“ฐ๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์กฐ์œจํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑํ•˜๋ผ

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

ํ”„๋กœ์„ธ์„œ ์ˆ˜๋ณด๋‹ค ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ๋ ค๋ณด๋ผ

์‹œ์Šคํ…œ์ด ์ž‘์—…์„ ์ „ํ™˜ํ•  ๋•Œ์—๋„ ๋ฌธ์ œ๋Š” ๋ฐœ์ƒํ•œ๋‹ค. ์ž‘์—… ์ „ํ™˜์„ ๋นˆ๋ฒˆํžˆ ๋ฐœ์ƒํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์„ธ์„œ ์ˆ˜๋ณด๋‹ค ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๋ผ. ์ž‘์—… ์ „ํ™˜์ด ์žฆ์„์ˆ˜๋ก ๋น ๋œจ๋ฆฐ critical section์ด๋‚˜ dead lock์„ ์ฐพ์„ ํ™•๋ฅ ์ด ๋†’์•„์ง€๊ฒŒ ๋œ๋‹ค.

๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ ๋Œ๋ ค๋ณด๋ผ

์šฐ๋ฆฌ(์ €์ž)๋Š” 2007๋…„ ์ค‘์ˆœ concurrent ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ•์ขŒ๋ฅผ ๊ฐœ๋ฐœํ–ˆ๋‹ค. ๊ฐ•์ขŒ์˜ ๊ฐœ๋ฐœ์€ OSX์—์„œ ์ง„ํ–‰๋˜์—ˆ์œผ๋ฉฐ ์‹œ์—ฐ์€ VM์ƒ์˜ Windows XP์—์„œ ์ง„ํ–‰๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹คํŒจ๋ฅผ ์‹œ์—ฐํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ๋Š” OSX์—์„œ๋Š” ์ž์ฃผ ๋ฐœ์ƒํ–ˆ์ง€๋งŒ Windows XP์—์„œ๋Š” OSX์—์„œ๋งŒํผ ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋กœ ์ธํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ์šด์˜์ฒด์ œ๋Š” ์ƒ์ดํ•œ ์Šค๋ ˆ๋”ฉ ์ •์ฑ…์„ ๊ฐ€์ง€๋ฉฐ ์ฝ”๋“œ์˜ ์‹คํ–‰์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค๋Š” ๊ฒƒ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๊นจ๋‹ซ๊ฒŒ ๋˜์—ˆ๋‹ค. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋Š” ์‹คํ–‰ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹น์‹ ์€ ๋ชจ๋“  ์ž ์žฌ์  ๋ฐฐํฌ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ถ”์ฒœ: ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์ด๋ฅธ ์‹œ๊ธฐ์—, ๋นˆ๋ฒˆํ•œ ์ฃผ๊ธฐ๋กœ ๋ชจ๋“  ํƒ€๊ฒŸ ํ”Œ๋žซํผ์—์„œ ์ˆ˜ํ–‰ํ•˜๋ผ.

์ฝ”๋“œ์— ๋ณด์กฐ ์ฝ”๋“œinstrument๋ฅผ ๋„ฃ์–ด ๋Œ๋ ค๋ผ. ๊ฐ•์ œ๋กœ ์‹คํŒจ๋ฅผ ์ผ์œผํ‚ค๊ฒŒ ํ•ด๋ณด๋ผ

์Šค๋ ˆ๋“œ ๊ด€๋ จ ๋ฌธ์ œ๋Š” ์ˆ˜๋งŽ์€ ์‹คํ–‰ ๊ฒฝ๋กœ์ค‘ ์–ผ๋งˆ ์•ˆ๋˜๋Š” ํ™•๋ฅ ๋กœ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋“œ๋ฌผ๊ฒŒ ๋ฐœ์ƒํ•˜๋ฉฐ ์žฌํ˜„ํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์ด ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ์กฐ์ž‘ํ•ด ์Šค๋ ˆ๋“œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ํ™•๋ฅ ์„ ๋†’์ด๋Š” code instrumentation์—๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

  • ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ
  • ์ž๋™ํ™”

์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ

์ด๋Š” Object.wait(), Object.sleep(), Object.yield(), Object.priority()๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ๋ณ€๊ฒฝํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์˜ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

public synchronized String nextUrlOrNull() {
    if(hasNext()) {
        String url = urlGenerator.next();
        Thread.yield();
        // inserted for testing.
        updateHasNext();
        return url;
    }
    return null;
}

yield() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ์ฝ”๋“œ์˜ ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์œ„ ์ฝ”๋“œ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ์ด๋Š” yield()๋ฅผ ์ถ”๊ฐ€ํ•ด ์ƒ๊ธด ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ๋ช…๋ฐฑํžˆ ๋งŒ๋“ ๊ฒƒ ๋ฟ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์—๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

  • ํ…Œ์ŠคํŠธํ•  ๋ถ€๋ถ„์„ ์ง์ ‘ ์ฐพ์•„์•ผ ํ•œ๋‹ค.
  • ์–ด๋””์— ์–ด๋Š ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ• ์ง€ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค.
  • ์ด์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ œํ’ˆ์— ํฌํ•จํ•ด ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ํผํฌ๋จผ์Šค๋ฅผ ์ €ํ•˜์‹œํ‚ฌ ๋ฟ์ด๋‹ค.
  • Shotgun approach์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋ณด์žฅ์„ ์–ป์„ ์ˆ˜ ์—†๋‹ค.

์šฐ๋ฆฌ๋Š” ์‹ค์ œ ์ œํ’ˆ์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉฐ ์—ฌ๋Ÿฌ ์กฐํ•ฉ์œผ๋กœ ์‹คํ–‰ํ•ด ์—๋Ÿฌ๋ฅผ ์ฐพ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์‹œ์Šคํ…œ์„ ์ตœ๋Œ€ํ•œ POJO ๋‹จ์œ„๋กœ ๋‚˜๋ˆ  instrument code๋ฅผ ์‚ฝ์ž…ํ•  ๋ถ€๋ถ„์„ ์ฐพ๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ณ  ์—ฌ๋Ÿฌ ์ •์ฑ…์— ๋”ฐ๋ผ sleep, yield๋“ฑ์„ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค.

์ž๋™ํ™”

์œ„์™€ ๋‹ค๋ฅด๊ฒŒ Aspect-oriented Framework, CGLib, ASM๋“ฑ์„ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ๋ฅผ ๋ณด์ž.

public class ThreadJigglePoint {
    public static void jiggle() { }
}
 
public synchronized String nextUrlOrNull() {
    if(hasNext()) {
        ThreadJiglePoint.jiggle();
        String url = urlGenerator.next();
        ThreadJiglePoint.jiggle();
        updateHasNext();
        ThreadJiglePoint.jiggle();
        return url;
    }
    return null;
}

์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•œ ํ›„ ๊ฐ„๋‹จํ•œ Aspect๋ฅผ ์ด์šฉํ•ด โ€˜์•„๋ฌด ๊ฒƒ๋„ ์•ˆํ•˜๊ธฐโ€™, โ€˜sleepโ€™, โ€˜yieldโ€™๋“ฑ์„ ๋ฌด์ž‘์œ„๋กœ ์„ ํƒํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜น์€ ThreadJigglePoint๊ฐ€ ๋‘ ๊ฐ€์ง€ ๊ตฌํ˜„์„ ๊ฐ€์ง€๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๊ตฌํ˜„์€ ๋ฐฐํฌ์šฉ ์ฝ”๋“œ๋ฅผ ์œ„ํ•œ โ€˜์•„๋ฌด ๊ฒƒ๋„ ์•ˆํ•˜๊ธฐโ€™๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ๋‘ ๋ฒˆ์งธ ๊ตฌํ˜„์€ โ€˜sleep, yield, ์•„๋ฌด ๊ฒƒ๋„ ์•ˆํ•˜๊ธฐโ€™ ์ค‘์˜ ํ•˜๋‚˜๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋‹ค์†Œ ๊ฐ„๋‹จํ•˜๊ธด ํ•˜์ง€๋งŒ ์ข€ ๋” ์ •๊ตํ•œ ํˆด์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ด ์ •๋„๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋„ ์ ์ ˆํ•œ ์„ ํƒ์ผ ๊ฒƒ์ด๋‹ค.

ํ˜น์€ ์ด์™€ ๋น„์Šทํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด ์ฃผ๋Š” IBM์—์„œ ๊ฐœ๋ฐœํ•œ ConTest๋ผ๋Š” ํˆด๋„ ์žˆ๋‹ค. ์ด๋Š” ์ˆ˜ํ–‰์‹œ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์Šค๋ ˆ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ์คŒ์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•  ํ™•๋ฅ ์„ ๊ทน์ ์œผ๋กœ ๋†’์—ฌ์ค€๋‹ค.

๊ฒฐ๋ก 

Concurrent ์ฝ”๋“œ๋Š” ์ œ๋Œ€๋กœ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์™€ ๊ณต์œ  ์ž์›์ด ์—ฎ์ด๊ฒŒ ๋˜๋ฉด ๋”์ฐํ•œ ๊ฒฐ๋ง์„ ๋‚ณ๊ฒŒ ๋œ๋‹ค. ๋‹น์‹ ์ด concurrent code๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์—„๊ฒฉํ•œ ๊ธฐ์ค€์œผ๋กœ cleanํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ผ.

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ฐพ๊ธฐ ์–ด๋ ต๊ณ  ๋นˆ๋ฒˆํ•˜์ง€ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ์ตœ์šฐ์„ ์ ์œผ๋กœ SRP๋ฅผ ์ˆ™์ง€ํ•˜๋ผ. ์‹œ์Šคํ…œ์„ ์ตœ๋Œ€ํ•œ POJO๋‹จ์œ„๋กœ ์ž˜๋ผ ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ฝ”๋“œ์™€ ้ž ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆ„์–ด๋ผ. ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ์—๋Š” ๊ทธ ์ด์™ธ์˜ ๊ฒƒ๋“ค์€ ์ œ์™ธํ•˜๊ณ  ์Šค๋ ˆ๋“œ ๊ด€๋ จ ๋ฌธ์ œ๋งŒ ํ…Œ์ŠคํŠธํ•˜๋ผ. ์ด๋Š” ์Šค๋ ˆ๋“œ ๊ด€๋ จ ๋ฌธ์ œ๊ฐ€ ์ตœ๋Œ€ํ•œ ์ž‘์€ ๋ถ€๋ถ„์— ์ง‘์ค‘๋˜๊ฒŒ ํ•œ๋‹ค.

ํ•œ ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์ˆ˜ํ–‰, ๊ณต์œ ๋˜๋Š” ์ž์› ํ’€ ๋“ฑ concurrency ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ธ์ง€ํ•˜๋ผ. ๊น”๋”ํ•˜๊ฒŒ ์ข…๋ฃŒ๋˜๊ฒŒ ํ•˜๋Š” ๋ฌธ์ œ๋‚˜ ๋ฐ˜๋ณต๋ฌธ ํƒˆ์ถœ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋Š” ํŠนํžˆ ์„ฑ๊ฐ€์‹ค ์ˆ˜ ์žˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ๊ธฐ๋ณธ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ดํ•ดํ•˜๋ผ. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์–ด๋–ป๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋ผ.

์ž ๊ฐ€์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๋ถ€๋ถ„์„ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๊ณ  ์ž ๊ฐ€๋ผ. ์“ธ๋ฐ ์—†๋Š” ๊ตฌ๊ฐ„์„ ์ž ๊ทธ์ง€ ๋งˆ๋ผ. ์ž ๊ธด ๊ตฌ๊ฐ„์—์„œ ๋˜ ๋‹ค๋ฅธ ์ž ๊ธด ๊ตฌ๊ฐ„์„ ๋ถ€๋ฅด๋Š” ๊ฒƒ์„ ๊ธฐํ”ผํ•˜๋ผ. ์ด๋Š” โ€œ๋ฌด์—‡์ด ๊ณต์œ ๋˜๊ณ  ์•ˆ๋˜๊ณ โ€์— ๋Œ€ํ•œ ๊นŠ์€ ์ดํ•ด๋ฅผ ์š”๊ตฌํ•œ๋‹ค. ๊ณต์œ  ๊ฐ์ฒด์˜ ๊ฐฏ์ˆ˜์™€ ๊ณต์œ  ์˜์—ญ์„ ์ตœ์†Œํ•œ์œผ๋กœ ์ค„์—ฌ๋ผ. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ณต์œ  ๊ฐ์ฒด์˜ ์ƒํƒœ(์ž ๊ธˆ ๋“ฑ)๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋Œ€์‹  ๊ณต์œ  ๊ฐ์ฒด์˜ ๋””์ž์ธ์„ ๋ณ€๊ฒฝํ•˜๋ผ.

๋ฌธ์ œ๋Š” ๋Œ์—ฐ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ฌธ์ œ๋“ค์€ ๋ณดํ†ต โ€œํ•œ๋ฒˆ๋งŒ ๋ฐœ์ƒํ•˜๋Š”โ€ ๋ฌธ์ œ๋กœ ์น˜๋ถ€๋œ๋‹ค. ์ด๋Ÿฌํ•œ one-off๋“ค์€ ๋ณดํ†ต ์‹œ์Šคํ…œ์— ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆฐ ๊ฒฝ์šฐ, ํ˜น์€ ๋ฌด์ž‘์œ„๋กœ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ์„ค์ •, ํ™˜๊ฒฝ์—์„œ ๋ฐ˜๋ณต์ ์ด๊ณ  ์ง€์†์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ด ๋ณด๋ผ. ๋‹น์‹ ์˜ ์ฝ”๋“œ๋ฅผ ์‹œ๊ฐ„์„ ๋“ค์—ฌ instrumentํ•˜๊ฒŒ ๋˜๋ฉด ๋ฌธ์ œ์ ์„ ์ฐพ์„ ํ™•๋ฅ ์€ ๋†’์•„์งˆ ๊ฒƒ์ด๋‹ค. ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๊ณ  ์ž๋™ํ™” ํˆด์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ถœ์‹œํ•˜๊ธฐ ์ „๊นŒ์ง€ ์ตœ๋Œ€ํ•œ ์˜ค๋ž˜ ํ…Œ์ŠคํŠธ ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค Cleanํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์ œ๋Œ€๋กœ ๋œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ๊ฐ€๋Šฅ์„ฑ์€ ๊ธ‰๊ฒฉํžˆ ์˜ฌ๋ผ๊ฐˆ ๊ฒƒ์ด๋‹ค.

Reference