2010-05-11 20 views
9

Tôi có một đoạn mã (giản thể):Mở khóa trên ReentrantLock mà không IllegalMonitorStateException

if(reentrantLockObject.isLocked()) { 
     reentrantLockObject.unlock(); 
} 

nơi reentrantLockObject là java.util.concurrent.locks.ReentrantLock. Thỉnh thoảng tôi nhận được IllegalMonitorStateException. Đường nối khóa được giải phóng giữa cuộc gọi kiểm tra và mở khóa(). Làm cách nào để ngăn chặn ngoại lệ này?

+0

@Mihail, Nếu bạn không biết hay không phải chủ đề của bạn giữ khóa, tôi đề nghị bạn có thể làm điều gì sai. –

Trả lời

15

isLocked trả lại xem bất kỳ chủ đề nào giữ khóa. Tôi nghĩ rằng bạn muốn isHeldByCurrentThread:

if (reentrantLockObject.isHeldByCurrentThread()) { 
    reentrantLockObject.unlock(); 
} 

Có nói rằng, isHeldByCurrentThread được ghi chép lại là chủ yếu cho các mục đích chẩn đoán - nó sẽ là bất thường đối với đoạn mã này để có cách tiếp cận đúng. Bạn có thể giải thích lý do tại sao bạn nghĩ rằng bạn cần nó?

+0

Nhưng có thể bạn sẽ không muốn. –

+0

@Tom: Đúng - đó không phải là ý tưởng hay. Sẽ chỉnh sửa. –

6

Bạn cần sở hữu khóa để có thể mở khóa. reentrantLockObject.isLocked() chỉ đúng nếu một số chủ sở hữu khóa, không nhất thiết là bạn.

reentrantLockObject.lock(); 
    try{ 

     // do stuff 
    }finally{ 
     reentrantLockObject.unlock(); 
    } 

Đây là chủ sở hữu khóa để chúng có thể mở khóa.

3

ReentrantLock ném ngoại lệ này theo logic này:

if (Thread.currentThread() != getExclusiveOwnerThread()) { 
    throw new IllegalMonitorStateException(); 
} 

Vì vậy, giải pháp là để kiểm tra xem các chủ đề tương tự được mở khóa:

if (reentrantLockObject.isHeldByCurrentThread()) { 
    reentrantLockObject.unlock(); 
} 
Các vấn đề liên quan