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เฉพาะเมื่อได้ล็อก- ใช้เมื่อการพลาดล็อกยังมีทางเดินต่อได้