显示锁

ReentrantLock并不是一种代替内置加锁的方法,而是当内置加锁机制不适用时的一种可选择的高级功能。

1. Lock与ReentrantLock

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

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

ReentrantLock实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性。它还支持在Lock中定义的所有的获取锁的模式,并且与synchronized相比,它还为处理锁的不可用性问题提供了更高的灵活性。

内置锁在功能上的局限性:

无法中断一个正在等待获取锁的线程,或者无法在请求一个锁时无限的等下去...

  • 优点:由于内置锁必须在获取该锁的代码块中释放,从而简化了编码工作,并且与异常交互的很好
  • 无法实现非阻塞结构的加锁规则。
    Lock接口的标准使用方式:
Lock lock=new ReentrantLock();
...
lock.lock();
try{
  //更新对象状态
  //补货异常,在必要时回复不变性条件
} finally{
  lock.unlock;
}

该形式比内置锁复杂一些,必须在finally中释放锁。否则会导致一定的危险。这个也是ReentrantLock不能完全替代synchronized的原因,容易忘记在fianlly中释放锁。

1.1 轮询锁与定时锁

这两种锁的获取模式都是由tryLock方法实现的,具有更完善的错误恢复机制。并且可以避免死锁的发生:如果不能获得所有需要的锁,可以使用定时或者轮询的锁获取方式,从而使你可以重新获得控制权,它会释放已经获得的锁,然后重新尝试获取所有的锁。
当在带有时间限制的操作中调用一个阻塞方法时,她会根据剩余时间来提供一个时限,如果操作不能在相应的时间内给出结果,程序就会提前结束。然鹅内置锁很难实现带有时间限制的操作。

1.2 可中断的锁获取操作

lockInterrutibly方法能够在获得锁的同时保持对中断的响应,并且由于它处于Lock中,因此无需创建其他类型的不可中断阻塞机制。


2. 公平性

在ReentrantLock的构造函数中提供了两种公平性选择:

  • 创建一个公平的锁
    在公平的锁上,线程将按照它们发出请求的顺序来获得锁。
    在公平的锁中,如果有一个线程持有这个锁或者有其他线程在队列中等待这个锁,那么新发出请求的线程将被放入队列中。
    适用于持锁时间相对较长或者请求锁的平均时间间隔较长的情况。
  • 创建一个非公平的锁
    在非公平的锁上,允许插队:当一个线程请求非公平的锁时,如果再发出请求的同时,该锁的状态变为可用,那么该线程将跳过所有的等待线程并获得这个锁。
    在非公平的锁中,只有当锁被某个线程持有时,新发出的线程请求才会被放入到队列中。
    在大多数情况下,非公平的锁的性能都要高于公平锁的性能。
    在竞争激烈的情况下,非公平锁的性能高于公平锁性能的原因之一有:
    在恢复一个被挂起的线程与该线程真正被执行之间存在着严重的延迟!
    E.G.线程A持有一个锁,并且线程B请求这个锁,因此B被挂起。A释放锁的时候,B被唤醒,并且尝试再次获取这个锁。与此同时,C也在请求这个锁,那么C很有可能在B被完全唤醒之前获得、使用以及释放了这个锁。从而提高了吞吐量呀!

3. 在synchronized和ReentrantLock之间进行选择

内置锁仍具备的优势:

  • 为开发人员熟悉,并且简洁紧凑,还广为使用。
  • ReentrantLock的危险性高,仅当内置锁不能满足需求时,才会使用ReentrantLock
  • 在java5.0中,在线程转储中能给出在哪些调用帧中获得了哪些锁,并能够检测和识别发生死锁的线程。ReentrantLock的非块结构性仍意味着,获取锁的操作不能和特定的帧关联起来。
  • 未来更可能提升的是synchronized的性能

4. 读-写锁

一个资源可以被多个读操作访问,或者被一个写操作访问,二者不能同时进行。

public interface ReadWriteLock{
  Lock readLock();
  Lock writeLock();
}

要读取被ReadWriteLock保护的数据,首先必须获得读取锁,当需要修改由ReadWriteLock保护的数据时,必须先获得写入锁。看上去两个锁是独立的,但是读取锁和写入锁只不过是读写锁对象的不同视图。

ReadWriteLock中一些可选实现:

  • **释放优先 : ** 当一个写入操作释放写入锁时,并且队列中同时存在读线程和写线程,那么应该优先选择读线程,写线程,还是最先发出请求的线程?
  • **读线程插队: ** 如果锁是由读线程持有,但有写线程正在等待,那么新到达的读线程能否立即获得访问权,还是应该在写线程后面等待?如果允许读线程插入到写线程前面,有助于提高并发性,但是有可能造成写线程发生饥饿问题。
  • **重入性 : ** 读操作和写操作是否为可重入的?
  • **降级 : ** 如果一个线程持有写入锁,那么它能否在不释放该锁的情况下获取读取锁?这样可能会使得写入锁被降级为读取锁,同时不允许其他写线程修改被保护的资源。
  • **升级 : ** 读取锁能否优先于其他正在等待的读线程和写线程而升级为一个写入锁?

ReentrantReadWriteLock

ReentrantReadWriteLock为这两种锁都提供了可重入的加锁定义。并且在其构造函数内可选择一个公平锁或者非公平的锁(默认)。

  • 公平的锁中:等待时间最长的线程优先获得锁。如果这个锁被读线程持有,而另一个线程请求写入锁,那么其他读线程都不能获取读取锁,直到写线程使用完并且释放了写入锁。
  • 在非公平的锁中:线程获得访问许可的顺序是不确定的。写线程可以降级为读线程,但是读线程不能升级为写线程(导致死锁)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容