Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Thread Interference Error ใน Java (Race Condition)

Thread Interference / Race Condition

เกิดเมื่อ thread หลายตัว เข้าถึงและแก้ไข shared data พร้อมกัน โดยไม่มี synchronization ผลลัพธ์ขึ้นอยู่กับลำดับการรัน (non-deterministic)

ตัวอย่าง


class Counter {
    static int value = 6;
    
    void increment() {
        for (int i = 0; i < 10; i++) {
            value++;
            System.out.println("Inc: " + value);
        }
    }
    
    void decrement() {
        for (int i = 0; i < 10; i++) {
            value--;
            System.out.println("Dec: " + value);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        Counter c = new Counter();
        new Thread(c::increment).start();
        new Thread(c::decrement).start();
    }
}

ผลลัพธ์ (ตัวอย่าง - ไม่คงที่)

Inc: 7
Inc: 8
Dec: 7
Inc: 8
Dec: 7
...

ปัญหา: value++ ไม่ใช่ atomic ประกอบด้วย 3 ขั้นตอน: Read → Modify → Write Thread อาจถูก interrupt ระหว่างขั้นตอน ทำให้ update หายไป

วิธีแก้

1. synchronized method


synchronized void increment() { ... }
synchronized void decrement() { ... }

2. synchronized block (fine-grained)


void increment() {
    for (int i = 0; i < 10; i++) {
        synchronized(this) { value++; }
    }
}

3. AtomicInteger (lock-free, แนะนำ)


import java.util.concurrent.atomic.AtomicInteger;

class Counter {
    AtomicInteger value = new AtomicInteger(6);
    
    void increment() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Inc: " + value.incrementAndGet());
        }
    }
    // decrement: value.decrementAndGet()
}

สรุป

  • Thread interference = Race condition บน shared mutable state
  • แก้ด้วย synchronization (synchronized, Lock, Atomic classes)
  • Atomic classes เร็วกว่า synchronized สำหรับ operation เรียบง่าย
  • Immutable objects ป้องกันปัญหานี้ได้โดยรากฐาน