美文网首页
JDK并发包之重入锁

JDK并发包之重入锁

作者: xinxinlimin | 来源:发表于2017-10-26 10:46 被阅读0次

锁:对共享数据加锁使其变为临界区。(排它锁)与共享锁

锁有内部锁(synchronized关键字修饰的)与显式锁(Java.concurrent.locks.Lock接口)。

显式锁与内部锁的比较

各适用环境不同,而非相互代替,内部锁申请或者释放一个锁必须在块或者同一方法中,灵活性更差,但方便,不会导致锁泄露;而显式锁可以跨方法释放锁,灵活性更高,但容易锁泄露,操作不方便,繁琐。同时显示锁支持狠多内部锁不支持的特性。

显式锁之重入锁:

重入锁存在于Java.util.concurrent.locks.ReentrantLock类。

例如:

之所以称为重入锁,是因为可以同一线程重复上锁,即两次上锁,两次释放锁。

中断响应:指两个线程出现死锁可以控制一方放弃申请锁,并释放已获得锁

首先营造一个死锁:

对于这种情况,我们能想到的办法为中断其中一个线程,即:

但这种方式需要在run方法中加isinterrupted作为标志位,只有为TRUE,才可中断,所以:

不需标志位判断

两种中断比较:

lock()加锁 lockInterruptibly()加锁

锁申请限时等待:

除了外部通知某个线程中断来处理死锁外,避免死锁还有另外方法:tryLock()

输出结果图p75

所以,对于上面的死锁问题,我们可以这样解决:

else同理

这样,经过几秒后,线程t1与t2都会得到锁资源并顺利执行完毕。

公平锁:

不会产生饥饿现象,synchronized不允许公平锁

说明:ReentrantLock(true)表示公平锁,其看来优美,但要实现公平锁,需要维护一个有序队列,因此公平锁实现成本高,性能低下,因此,一般情况下,锁是非公平的。如果没有特殊要求,也不推荐使用公平锁。

对于系统调度而言,一个线程更倾向于再此获得已经持有的锁,这种分配方式是高效的。

使用公平锁的结果就是,以时间片为单位,交替获得,而不公平锁大部分都是重复输出。

总结:重入锁的几个重要方法:

ReentrantLock()构造方法:实现公平非公平锁

lock():获得锁

lockInterruptibly():获得锁,但优先响应中断

tryLock():获得锁(资源),若锁被占用,返回false

tryLock(long time,TimeUnit unit):给定时间内获得锁

unlock():释放锁,千万不要忘记。

相关文章

网友评论

      本文标题:JDK并发包之重入锁

      本文链接:https://www.haomeiwen.com/subject/bqfqpxtx.html