ReentrantLock

Java5.0增加了一种新的机制:ReentrantLock。当内置加锁机制不适应时,ReentrantLock作为一种可选择的高级功能。

Lock与ReentrantLock

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

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

ReentrantLock实现了Lock接口,与synchronized一样,提供了可重入的加锁语句。ReentrantLock支持在Lock接口中定义的所有获取锁模式,与synchronized相比,它还为处理锁的不可用性问题提供了更高的灵活性。
使用ReentrantLock来保护对象状态:

Lock lock = new ReentrantLock();
        lock.lock();
        try {
            ..........
        }finally {
            lock.unlock();
        }

轮询锁与定时锁
在内置锁中,死锁是一个严重的问题,恢复程序的唯一方法是重新启动程序,而防止死锁的唯一方法就是在构造程序时避免出现不一致的锁顺序。可定时的与可轮询的锁提供了另一种选择:避免死锁的发生。
可定时的与可轮询的锁获取方式是由tryLock方法实现的。

/** Acquires the lock only if it is not held by another thread at the time of invocation. */
public boolean tryLock(){}
/**Acquires the lock if it is not held by another thread within the given waiting time and the current thread has not been interrupted*/
public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException{}

可定时的与可轮询的锁获取方式,它会释放已经获得的锁,然后重新尝试获取所有锁(或者至少会将这个失败记录到日志,并采取其他措施)。
通过tryLock来避免顺序死锁:

if (fromAcct.lock.tryLock()){
                try{
                    if (toAcct.lock.tryLock()){
                        try{
                           ............. 
                        }finally {
                            toAcct.lock.unlock();   
                        }
                    }
                }finally {
                    fromAcct.lock.unlock();
                }
            }

如上代码,使用tryLock来获取两个锁,如果不能同时获得,那么回退并重新尝试。
在实现具有时间限制的操作时,定时锁同样非常有用。
当在带有时间限制的操作中调用了一个阻塞方法时,它能根据剩余时间来提供一个时限。如果操作不能在指定时间内给出结果,那么程序就会提前结束。
带有时间限制的加锁:

 if (!lock.tryLock(3000, TimeUnit.SECONDS)){
            return false;
        }
 try {
         return true;
     }finally {
         lock.unlock();
     }

可中断的锁获取操作
正如定时的锁获取操作能在带有时间限制的操作中使用独占锁,可中断的锁获取操作同样能在可取消的操作中使用加锁。
lockInterruptibly方法能够在获得锁的同时保持对中断的响应,并且由于它包含在Lock中,因此无须创建其他类型的不可中断阻塞机制。

/*Acquires the lock unless the current thread is interrupted*/
void lockInterruptibly() throws InterruptedException;

可中断的锁的获取操作

lock.lockInterruptibly();
    try {
         return cancel();
     }finally {
        lock.unlock();
     }

public boolean cancel() throws  InterruptedException{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值