[Java] ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๊ฒฝ์Ÿ ์ƒํƒœ์™€ ํ•ด๊ฒฐ ์ „๋žต ์ •๋ฆฌ

2025. 6. 2. 21:58ยทโ˜•Java

๐Ÿš€ ๊ฒฝ์Ÿ ์ƒํƒœ

 

[OS] ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์—์„œ ๊ฒฝ์Ÿ ์ƒํƒœ ํ•ด๊ฒฐ: ์ƒํ˜ธ ๋ฐฐ์ œ (๋ฎคํ…์Šค์™€ ์„ธ๋งˆํฌ์–ด)

๐Ÿ“Œ ์˜ค๋Š˜ ์ฃผ์ œ์ธ ๊ฒฝ์Ÿ ์ƒํƒœ์™€ ์ƒํ˜ธ ๋ฐฐ์ œ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์™ธ์—๋„ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์Šค์—์„œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ด์ง€๋งŒ์ œ๊ฐ€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด ๋ฐฐ์šฐ๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์œผ๋กœ, ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด์„œ๋งŒ ์ค‘์ ์ 

syleeblog.tistory.com

 

์ด์ „ ๊ธ€์—์„œ๋Š”

์šด์˜ ์ฒด์ œ ๊ด€์ ์—์„œ ๊ฒฝ์Ÿ ์ƒํƒœ์˜ ์ •์˜ ๊ทธ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ƒํ˜ธ ๋ฐฐ์ œ์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š”

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋ฅผ ์ง€์›ํ•˜๋Š” Java์—์„œ ๊ฒฝ์Ÿ ์ƒํƒœ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๊ฒฐ ์ „๋žต์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด์ „ ๊ธ€์—์„œ ๊ฒฝ์Ÿ ์ƒํƒœ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃจ์—ˆ๋Š”๋ฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜์ž๋ฉด

๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)๋ž€, ๋‘˜ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ์ž์›์— ์ ‘๊ทผํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋ ค๊ณ  ํ•  ๋•Œ

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


๐Ÿ“Œ synchronized ํ‚ค์›Œ๋“œ

Java์—์„œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋™๊ธฐํ™” ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค. ํŠน์ • ๋ฉ”์„œ๋“œ๋‚˜ ๋ธ”๋ก์— synchronized๋ฅผ ์ง€์ •ํ•˜๋ฉด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ํ•ด๋‹น ์ฝ”๋“œ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

public synchronized void increment() {
    counter++;
}

 

  • โœ… ์žฅ์ 
    • ์‚ฌ์šฉ์ด ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.
    • ๋ฉ”์„œ๋“œ ์ „์ฒด ํ˜น์€ ํŠน์ • ๋ธ”๋ก์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • โš ๏ธ ์ฃผ์˜
    • ์„ธ๋ฐ€ํ•œ ์ œ์–ด๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ Lock ์ธํ„ฐํŽ˜์ด์Šค

java.util.concurrent.locks.Lock์€ synchronized๋ณด๋‹ค ๋” ์ •๊ตํ•œ ๋™๊ธฐํ™” ์ œ์–ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

์ฃผ์š” ๊ตฌํ˜„์ฒด๋กœ ReentrantLock์ด ์žˆ์Šต๋‹ˆ๋‹ค.

lock.lock();
try {
    // ์ž‘์—… ์ˆ˜ํ–‰
} finally {
    lock.unlock();
}

 

  • ๊ณต์ •์„ฑ ์„ค์ •, ํƒ€์ž„์•„์›ƒ ๋Œ€๊ธฐ, ์กฐ๊ฑด ๋ณ€์ˆ˜(Condition) ๋“ฑ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • finally ๋ธ”๋ก์—์„œ ๋ฐ˜๋“œ์‹œ unlock()์„ ํ˜ธ์ถœํ•ด ๋ฝ์„ ํ’€์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ Atomic ํด๋ž˜์Šค ์‚ฌ์šฉ

AtomicInteger, AtomicLong ๋“ฑ์€ ๋‚ด๋ถ€์ ์œผ๋กœ CAS(Compare-And-Swap) ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ

๋ฝ ์—†์ด๋„ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ, ์›์ž์  ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();

 

  • โœ… ์žฅ์ 
    • ๋น„๋™๊ธฐ ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฝ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๊ฐ„๋‹จํ•œ ์—ฐ์‚ฐ์—์„œ ์†๋„๊ฐ€ ๋งค์šฐ ๋น ๋ฆ…๋‹ˆ๋‹ค.
  • โš ๏ธ ์ฃผ์˜
    • ๋ณต์žกํ•œ ์—ฐ์‚ฐ์—๋Š” ์ ์ ˆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ Concurrent ์ปฌ๋ ‰์…˜ ํ™œ์šฉ

ConcurrentHashMap, CopyOnWriteArrayList ๋“ฑ์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ์„ค๊ณ„๋œ ์ปฌ๋ ‰์…˜์ž…๋‹ˆ๋‹ค.

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

ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueue ๋“ฑ

 

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ „ํ•œ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋ถˆ๋ณ€ ๊ฐ์ฒด(Immutable Object) ํ™œ์šฉ

๊ฐ€๋Šฅํ•˜๋ฉด ๊ณต์œ  ์ž์›์„ ์“ฐ์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

 

๊ฒฝ์Ÿ ์ƒํƒœ ์ž์ฒด๋ฅผ ํšŒํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถˆ๋ณ€ ๊ฐ์ฒด๋ž€, ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

ํ•„๋“œ๊ฐ€ ๋ชจ๋‘ final๋กœ ์„ ์–ธ๋˜๊ณ , ์™ธ๋ถ€์—์„œ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

public final class User {
    private final String name;
    private final int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
}

 

์ƒํƒœ ๋ณ€๊ฒฝ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝ์Ÿ ์ƒํƒœ ์ž์ฒด๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋“œ ๊ฐ„ ๊ณต์œ ํ•ด๋„ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.


๊ฒฐ๋ก 

๊ฒฝ์Ÿ ์ƒํƒœ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์—์„œ ํ”ํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ ์ƒํ™ฉ์— ๋งž๋Š” ๋™๊ธฐํ™” ์ „๋žต์„ ์„ ํƒํ•˜์—ฌ ์„ฑ๋Šฅ๊ณผ ์•ˆ์ •์„ฑ์˜ ๊ท ํ˜•์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

'โ˜•Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[JAVA] ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (๋ฐฑ์ค€ 12891๋ฒˆ)  (1) 2025.05.22
[JAVA] ํˆฌ ํฌ์ธํ„ฐ (๋ฐฑ์ค€ 2018๋ฒˆ, ๋ฐฑ์ค€ 1940๋ฒˆ)  (3) 2025.05.18
[JAVA] ๊ตฌ๊ฐ„ ํ•ฉ ๊ตฌํ•˜๊ธฐ (๋ฐฑ์ค€ 11659๋ฒˆ, ๋ฐฑ์ค€ 2042๋ฒˆ)  (1) 2025.05.17
[JAVA] ๋ฐฐ์—ด๊ณผ ๋ฆฌ์ŠคํŠธ: ์ˆซ์ž์˜ ํ•ฉ ๊ตฌํ•˜๊ธฐ(๋ฐฑ์ค€ 11720)  (3) 2025.05.14
[์ž๋ฃŒ๊ตฌ์กฐ][Java] HashSet ์ค‘๋ณต ์ œ๊ฑฐ ๋™์ž‘ ์›๋ฆฌ: HashSet์€ ์–ด๋–ป๊ฒŒ ์ค‘๋ณต์„ ํ™•์ธํ•˜๋‚˜์š”?  (0) 2025.02.13
'โ˜•Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [JAVA] ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (๋ฐฑ์ค€ 12891๋ฒˆ)
  • [JAVA] ํˆฌ ํฌ์ธํ„ฐ (๋ฐฑ์ค€ 2018๋ฒˆ, ๋ฐฑ์ค€ 1940๋ฒˆ)
  • [JAVA] ๊ตฌ๊ฐ„ ํ•ฉ ๊ตฌํ•˜๊ธฐ (๋ฐฑ์ค€ 11659๋ฒˆ, ๋ฐฑ์ค€ 2042๋ฒˆ)
  • [JAVA] ๋ฐฐ์—ด๊ณผ ๋ฆฌ์ŠคํŠธ: ์ˆซ์ž์˜ ํ•ฉ ๊ตฌํ•˜๊ธฐ(๋ฐฑ์ค€ 11720)
์†Œ์˜ ๐Ÿ€
์†Œ์˜ ๐Ÿ€
Hello World โœจ
  • ์†Œ์˜ ๐Ÿ€
    Soyoung's Dev Lab
    ์†Œ์˜ ๐Ÿ€
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ธ€์“ฐ๊ธฐ ๊ด€๋ฆฌ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (47)
      • ๐Ÿ“ข ๊ฒŒ์‹œํŒ (0)
      • ๐Ÿ“š ์ž๋ฃŒ๊ตฌ์กฐ & ์•Œ๊ณ ๋ฆฌ์ฆ˜ (1)
      • ๐ŸŒฟSpring (15)
      • โ˜•Java (8)
      • ๐Ÿ“Š ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (3)
      • ๐Ÿ“ค ๋ฐฐํฌ (4)
        • Docker (4)
        • AWS (0)
      • โš™๏ธ CS & ๊ธฐํƒ€ ๊ฐœ๋ฐœ ์ž๋ฃŒ (14)
      • ๐Ÿ–ฅ๏ธ ํ”„๋กœ์ ํŠธ (0)
      • ๐Ÿ‘ฉ‍๐Ÿ’ป ํ™œ๋™ & ํ›„๊ธฐ (0)
      • ๐Ÿต ์ด์•ผ๊ธฐ (2)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํƒœ๊ทธ
  • ๋งํฌ

    • github
    • velog
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๊ฐ์ฒด์ง€ํ–ฅํ”„๋กœ๊ทธ๋ž˜๋ฐ
    ๋ฐฐํฌ
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ์„œ๋ฒ„
    ์œ„ํด๋ฆฌ ํŽ˜์ดํผ
    ์ฝ”๋“œ์ž‡ ์Šคํ”„๋ฆฐํŠธ
    Spring
    Spring Security
    docker
    GIT
    ๊ฐœ๋ฐœ
    ์ž๋ฃŒ๊ตฌ์กฐ
    Java
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
์†Œ์˜ ๐Ÿ€
[Java] ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๊ฒฝ์Ÿ ์ƒํƒœ์™€ ํ•ด๊ฒฐ ์ „๋žต ์ •๋ฆฌ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”