Lock提供了一种无条件的,可轮询的,定时的,可中断的锁获取操作

轮询锁与定时锁

如果不能同时获取所需要的所有的锁,那么就可以使用可定时的或可轮询的锁获取方式来保证安全性。
如果得不到所有的锁,那么释放已经获得的所有的锁,并尝试重新获取锁。

  1. long endTime=now()+duration;
  2. Lock lock;
  3. while(true){
  4. if(lock.lockA.tryLock){
  5. try{// 如果请求不到所有的锁,释放已经有的锁
  6. if(lock.lockB.tryLock){
  7. try{
  8. // dosomething();
  9. // return;
  10. }finally{
  11. lock.lockB.unlock();
  12. }
  13. }
  14. }finally{
  15. lock.lockA.tryLock
  16. }
  17. }
  18. if(endTime < now()) { // 指定了时间的限制
  19. return false;
  20. }
  21. // 睡一下,重新尝试获取锁
  22. Thread.sleep(xxx);
  23. }

可中断的锁

使用Lock的**void **``lockInterruptibly() ``**throws **``InterruptedException;方法,
可以在获得锁的同时保持对中断的响应,被中断则抛出InterruptedException异常

  1. func() throw InterruptedException{
  2. lock.lockInterruptibly();
  3. try{
  4. dosomething()
  5. }finally{
  6. lock.unlock();
  7. }
  8. }

所有加锁、解锁都是显式的

  • 必须在finally中lock.unlock()

使用它的理由:

  • 可以中断一个正在等待获取锁的线程
  • 取消一个等待锁时间过长的线程
  • 可以提供更灵活的加锁机制