一、Lock与ReentrantLock

Lock接口中定义了一种无条件、可轮询的、定时的以及可中断的锁获取操作,所有加锁和解锁的方法都是显式的。

 1 public interfece Lock
 2 {
 3     void lock();
 4     void lockInterruptibly() throws InterruptedException;
 5     boolean tryLock();
 6     boolean tryLock(long timeout, TimeUnit unit 
 7         throw InterruptedException;
 8     void unlock();
 9     Condition newCondition();
10 }

ReentrantLock实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性。ReentrantLock同样提供了可重入的加锁语义

1 Lock lock = new ReentrantLock();
2 ...
3 lock.lock();
4 try {
5     // 更新对象状态
6     // 捕获异常,并在必要时恢复不变性条件
7 } finally {
8     lock.unlock();//一定要记得在finally块里释放
9 }

1、轮询锁与定时锁

  • 轮询锁和定时锁可由tryLock来实现
  • 轮询锁,定时锁可以避免死锁的发生
  • 轮询锁通过释放已获得的锁,并退回重新尝试获取所有锁(lock.tryLock(),定时锁通过释放已获得的锁,放弃本次操作(lock.tryLock(timeout, unit)来避免死锁

 

 1 while (true) {
 2             if (fromAcct.lock.tryLock()) {
 3                 try {
 4                     if (toAcct.lock.tryLock()) {
 5                         try {
 6                             if (fromAcct.getBalance().compareTo(amount) < 0)
 7                                 throw new InsufficientFundsException();
 8                             else {
 9                                 fromAcct.debit(amount);
10                                 toAcct.credit(amount);
11                                 return true;
12                             }
13                         } finally {
14                             toAcct.lock.unlock();
15                         }
16                     }
17                 } finally {
18                     fromAcct.lock.unlock();
19                 }
20             }
21             if (System.nanoTime() < stopTime)
22                 return false;
23             NANOSECONDS.sleep(fixedDelay + rnd.nextLong() % randMod);
24         }
25     }
轮询锁

相关文章: