重入锁ReentrantLock

synchronized的功能扩展:重入锁

概念

重入锁完全可以替代关键字synchronized. 在jdk5.0以前的版本中,重入锁的性能远远优于关键字synchronized。但在6.0以后,JDK在 关键字synchronized上做了大量优化,使得两者性能差距不大。重入锁有着显示的操作过程。开发人员必须手动指定何时加锁,何时释放锁。你可能对重入两字感到疑惑,从类的命名来看,Re-Entrant-Lock 翻译成重入锁非常贴切之所以这样叫,是因为这种锁是可以反复进入的当然,这里的反复仅仅限于一个线程里;如下面的代码所示

lock.lock();
lock.lock();
try{
i++
}finally{
lock.unlock();
lock.unlock();
}

在这种情况下,一个线程连续两次获得同一把锁是被允许的。如果不允许该操作,那么同一线程第一次获取该锁时便一直无法获取,形成死锁。在这里需要注意的 是申请了几次锁,就需要释放几次,释放的锁多了,那么会得到一个java.lang.IllegalMonitorStateException异常,反之释放锁少了,那么相当于线程还未释放该锁,其它线程继续等待

1.中断响应

对于关键字synchronized来说,线程只有两种状态,一种获取锁继续执行,一种处于等待过程中。而使用重入锁,便存在另一个可能,也就是在等待时,程序可以根据需求取消等待。这么做是非常有必要的,比如,你和朋友约好5点见面,你等到5.30你朋友还是没到,此时有人通知你,你朋友出车祸来不了了,此时你就会不在原地等待,而是打道回府或者去医院看望。中断便是这类机制。

2.锁申请等待限时

除了等待外部释放外,要避免死锁还有另外一种方法,就是限时等待,同样举例,你和你朋友约定好5.00见面,你等到5.30,他还是未能赴约,切不能联系上,这时我相信你不会一直傻等下去,而是提前离去。同样锁也可以,设置一部分时间,在超出时间后自动释放资源。常用ReentrantLock锁中的tryLock()方法实现,其中有两个参数,一个表示等待时常,另外一个表示计时单位。可以不设置参数。

3.公平锁

在大多数情况下,锁的申请都是非公平的。也就是说,线程获取资源的顺序并不是先来先获取,而是高优先级别的线程先获取,这样很容易导致低优先的线程一直无法获取锁或者资源,形成饥饿。如果我们使用synchronized锁那么默认都是非公平的,但是重入锁给我们提供了其公平性可设置。构造函数如下:

public ReentrantLock(boolean fair)

fair为true时,锁是公平的。公平锁看起来优美,但是实现公平锁必然需要维护一个有序队列,其实现成本高,性能低下,如果非特定情况,锁是非公平的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值