นากมิ้นต์ต้นฉบับลองแตะกุญแจประตูห้องแล็บ ถ้ายึดไม่ได้ก็หันไปทำงานกองอื่นบนโต๊ะครีม

Java ReentrantLock.tryLock: ลองคว้ากุญแจ ถ้าไม่ได้ก็ไม่ยืนรอ

น้องกายEngineering

synchronized ทำให้รอจนได้ล็อกครับ แต่บางงานถ้าแย่งไม่ได้ควรทำอย่างอื่นทันที เช่น ข้ามรอบอัปเดตแคชหรือคืนค่าเดิม ReentrantLock.tryLock() คืน true เมื่อคว้าได้ และ false เมื่อไม่ได้ โดยไม่บล็อก

WHY: กันคิวยาวตอนงานไม่จำเป็นต้องชนะทุกครั้ง

มีเวอร์ชันรับเวลา tryLock(long, TimeUnit) ถ้ายังไม่ได้เมื่อครบเวลาจะคืน false และโยน InterruptedException ถ้าถูกขัดจังหวะระหว่างรอ อย่าลืม unlock ใน finally เฉพาะเมื่อ tryLock สำเร็จ

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
  public static void main(String[] args) throws Exception {
    ReentrantLock lock = new ReentrantLock();
    CountDownLatch held = new CountDownLatch(1);
    CountDownLatch finished = new CountDownLatch(1);
    AtomicBoolean secondGotLock = new AtomicBoolean(true);

    Thread holder = new Thread(() -> {
      lock.lock();
      try {
        held.countDown();
        finished.await();
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      } finally {
        lock.unlock();
      }
    });

    holder.start();
    held.await();
    secondGotLock.set(lock.tryLock());
    finished.countDown();
    holder.join();

    assert !secondGotLock.get() : "tryLock should fail while held";
    assert lock.tryLock() : "tryLock should succeed after release";
    lock.unlock();
    System.out.println("ok");
  }
}

Recap

  • tryLock() ไม่รอ — ได้หรือไม่ได้ทันที
  • unlock เฉพาะเมื่อได้ล็อก
  • ใช้เมื่อการพลาดล็อกยังมีทางเดินต่อได้