Skip to content

Chapter 12. ๋™์‹œ ์„ฑ๋Šฅ ๊ธฐ๋ฒ•ย #12

@HaeUlNam

Description

@HaeUlNam

์ •๋ฆฌ

  • ๋ฌด์–ด์˜ ๋ฒ•์น™: ์นฉ ํ•˜๋‚˜์— ๊ฝ‚์„ ์ˆ˜ ์žˆ๋Š” ํŠธ๋žœ์ง€์Šคํ„ฐ ๊ฐœ์ˆ˜๊ฐ€ ๋งค๋…„ 2๋ฐฐ ์ฆ๊ฐ€. 50๋…„ ์ •๋„๋™์•ˆ์€ ์œ ํšจํ–ˆ์Œ.
  • ์•”๋‹ฌ์˜ ๋ฒ•์น™
    • T(N) = S + (1/N) * (T - S)
    • S: ์ˆœ์ฐจ ์‹คํ–‰ ํŒŒํŠธ
    • T: ์ด ํƒœ์Šคํฌ ์†Œ์š” ์‹œ๊ฐ„
    • N: ํ”„๋กœ์„ธ์„œ ๊ฐœ์ˆ˜
    • ๋™์‹œ ์ž‘์—…์€ T - S์ด๊ณ , N ๊ฐœ ํ”„๋กœ์„ธ์Šค์— ํƒœ์Šคํฌ๋ฅผ ๊ณ ๋ฃจ ๋ถ„๋ฐฐํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์ „์ฒด ํƒœ์Šคํฌ ์†Œ์š” ์‹œ๊ฐ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    • ๋‚ฏ๊ฐ„์ง€๋Ÿฌ์šด ๋ณ‘๋ ฌ: ๋ณ‘๋ ฌ ํƒœ์Šคํฌ๋‚˜ ๋‹ค๋ฅธ ์ˆœ์ฐจ ํƒœ์Šคํฌ ๊ฐ„์— ์†Œํ†ตํ•  ํ•„์š”๊ฐ€ ์ „ํ˜€ ์—†์„ ๊ฒฝ์šฐ ์ด๋ก ์ ์œผ๋กœ ์†๋„๋Š” ๋ฌดํ•œํžˆ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ์ž๋ฐ” ๋™์‹œ์„ฑ
    • volatile ํ‚ค์›Œ๋“œ
      • Main memory๋กœ๋ถ€ํ„ฐ ์ตœ์‹  ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•œ๋‹ค.
      • Thread Safety Case
        • ์˜ค์ง ํ•˜๋‚˜์˜ Thread๋งŒ writeํ•˜๋Š” ๊ฒฝ์šฐ
        • ์—ฌ๋Ÿฌ thread๊ฐ€ writeํ•˜์ง€๋งŒ Atomicํ•˜๊ฒŒ writeํ•˜๋Š” ๊ฒฝ์šฐ
      • Non-Thread Safety case
        • non-atomic/composite operation
        • e.g. ์ฆ๊ฐ€/๊ฐ์†Œ ์™€ ๊ฐ™์€ operation. ์ฆ๊ฐ€/๊ฐ์†Œ๋Š” 3๊ฐ€์ง€ operation(Read variable, Update, Writing the updated back to memory)์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์งง์€ ์‹œ๊ฐ„๋™์•ˆ race condition ๋ฐœ์ƒ ๊ฐ€๋Šฅ
      • https://www.baeldung.com/java-volatile-variables-thread-safety
  • JMM(Java Memory Model)์˜ ์ดํ•ด
  • CAS(Compare-And-Swap): non-blocking algorithms for concurrent environments. ๋‹จ์ผ ์—ฐ์‚ฐ์œผ๋กœ Read, Update, Writing the updated back to memory๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • Non-blocking algorithm: ํŠน์ • ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์—…์ด ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ๋Œ€๊ธฐ ์ƒํƒœ์— ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ์—, ๋‹ค๋ฅธ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋ผ๋„ ๊ทธ๋กœ์ธํ•ด ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ๋Œ€๊ธฐ ์ƒํƒœ์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ Non-Blocking ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ  ํ•œ๋‹ค. ๋˜ํ•œ ๊ฐ ์ž‘์—… ๋‹จ๊ณ„๋งˆ๋‹ค ์ผ๋ถ€ ์Šค๋ ˆ๋“œ๋Š” ํ•ญ์ƒ ์ž‘์—…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ Lock-Free ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ  ํ•œ๋‹ค.
    • JVM์—์„œ์˜ CAS ์ง€์›์€ Java 5.0์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘๋˜์—ˆ๊ณ , CAS ์—ฐ์‚ฐ์„ ์ง์ ‘ ์ง€์›ํ•˜๋Š” ํ•˜๋“œ์›จ์–ด์—์„œ๋Š” ํ•ด๋‹น ๋ถ€๋ถ„์„ ๊ธฐ๊ณ„์–ด๋กœ ๋ณ€ํ™˜.
    • https://effectivesquid.tistory.com/entry/Lock-Free-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Non-Blocking-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
  • Intrinsic lock vs spin lock
    • Intrinsic lock: ์œ ์ € ์ฝ”๋“œ์—์„œ OS๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ์ž‘๋™. OS๋ฅผ ์ด์šฉํ•ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋”ฐ๋กœ ์‹ ํ˜ธ๋ฅผ ์ค„ ๋–„๊นŒ์ง€ ๋ฌดํ•œ์ • ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ
    • Spin lock: ๋ธ”๋กœํ‚น๋œ ์Šค๋ ˆ๋“œ๋ฅผ CPU์— ํ™œ์„ฑ ์ƒํƒœ๋กœ ๋†”๋‘๊ณ , ์•„๋ฌด ์ผ๋„ ์‹œํ‚ค์ง€ ์•Š์€ ์ฑ„ ๊ณ„์† ์žฌ์‹œ๋„(CPU cycle ์†Œ๋ชจ)
  • ๋™์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • java.util.concurrent.locks.Lock interface
      • lock(): ๊ธฐ์กด ๋ฐฉ์‹๋Œ€๋กœ ๋ฝ์„ ํš๋“ํ•˜๊ณ  ๋ฝ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ธ”๋กœํ‚น
      • tryLock(): ๋ฝ์„ ํš๋“ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ , true/false๋ฅผ return. ํƒ€์ž„์•„์›ƒ ์„ค์ •๋„ ํ•  ์ˆ˜ ์žˆ์Œ.
      • ReentrantLock: Lock์˜ ๊ตฌํ˜„์ฒด
      • ReentrantReadWriteLock์˜ ReadLock๊ณผ WriteLock์„ ์‚ฌ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฝ๊ธฐ ์ž‘์—…์„ ํ•˜๋Š” ๋„์ค‘์—๋Š” ๋‹ค๋ฅธ ์ฝ๊ธฐ ์Šค๋ ˆ๋“œ๋ฅผ ๋ธ”๋กœํ‚นํ•˜์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ธ”๋กœํ‚น์€ ์“ฐ๊ธฐ๋งŒ ์ผ์–ด๋‚จ. ์ฝ๊ธฐ๊ฐ€ ๋งŽ์ด ์ผ์–ด๋‚˜๋Š” Application์—์„œ ์ข‹๋‹ค.
    • Semaphore: โ€˜์ตœ๋Œ€ O๊ฐœ ๊ฐ์ฒด๊นŒ์ง€๋งŒ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉโ€™๊ณผ ๊ฐ™์ด ์—ฌ๋Ÿฌ ๋ฆฌ์†Œ์Šค์˜ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋…ํŠนํ•œ ๊ธฐ์ˆ ์„ ์ œ๊ณต
      • acquire: ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํผ๋ฐ‹ ์ˆ˜๋ฅผ ํ•˜๋‚˜์”ฉ ์ค„์ž„. ์“ธ ์ˆ˜ ์žˆ๋Š” ํผ๋ฐ‹์ด ํ•˜๋‚˜๋„ ์—†์„ ๊ฒฝ์šฐ blocking
      • release: ํผ๋ฐ‹์„ ๋ฐ˜๋‚ฉํ•˜๊ณ  ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘์—์„œ ํ•˜๋‚˜์—๊ฒŒ ํ•ด์ œํ•œ ํผํ‚ท์„ ์ „๋‹ฌ
    • CountDownLatch: Count๋ฅผ ์…‹ํŒ…ํ•˜๊ณ , ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ countdown()์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์นด์šดํŠธ ๊ฐ’์„ 1 ๊ฐ์†Œํ•˜๊ณ , 0์— ์ด๋ฅด๋ฉด Latch๊ฐ€ ์—ด๋ฆฐ๋‹ค.
    • ForkJoinPool
      • ํ•˜์œ„ ๋ถ„ํ•  ํ…Œ์Šคํฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
      • ์ž‘์—… ๋นผ์•—๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜

์งˆ๋ฌธ

  • Q. ์™œ ์•ฝํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์ด ๊ฐ•ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ๋ณด๋‹ค ์ด์‹์„ฑ์ด ๋†’์€ ๊ฑด๊ฐ€? ์ตœ๊ทผ CPU ์•„ํ‚คํ…์ฒ˜๋“ค์ด ์•ฝํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์ด๋ผ์„œ?
  • Q. CountDownLatch๋Š” ํ˜„์žฌ ๋‹จ๊ณ„์˜ ๋ชจ๋“  ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ€์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ? ์‹ค์ œ ์ด๋Ÿฐ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋Š” ๊ฒŒ ์žˆ์„๊นŒ? ์จ๋ณธ์ ์ด ์—†์–ด์„œ...
  • Q. ์ฑ…์—์„œ๋Š” ๊ฒฝํ•ฉ ์ค‘์ธ ๋ฆฌ์†Œ์Šค๊ฐ€ ๊ทนํžˆ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ๋งŒ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Intrinsic lock ๋ฐฉ์‹์€ ๋ง‰๋Œ€ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๊ฒƒ์— ๊ณต๊ฐํ•˜์ง€๋งŒ, ๊ฒฝํ•ฉ ์ค‘์ธ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ทนํžˆ ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ์‚ฌ์šฉํ•˜๋Š”๊ฑธ ์–ด๋–ป๊ฒŒ ์•Œ์ง€?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions