Chapter 5 Java中的锁(一)

5.1 LOCK接口

锁是用于控制多个线程访问共享资源的方式。一般来说,一个锁能够防止多个线程同一时间访问一个共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁)。

Lock接口提供了与synchronized关键字类似的功能,只是在使用时需要显示的获取和释放锁。虽然它缺少了(synchronized块或方法所提供的)隐式获取和释放锁的便捷性,但是却拥有了锁获取与释放的可操作性可中断的获取锁以及超时获取锁等synchronized关键字所不具备的同步特性。

Lock接口的使用示例:

Lock lock = new ReentrantLock();

lock.lock();

try{

}finally{

      lock.unlock();

}

Lock 接口所提供的的synchronized关键字不具备的功能:

(1)尝试非阻塞的获取锁。

(2)能被中断地获取锁:与synchronized不同,当获取到锁的线程被中断时,中断异常将被抛出,同时锁被释放。

(3)超时获取锁:如果在规定时间内无法获得锁,则及时返回。


5.2 队列同步器

队列同步器AbstractQueuedSynchronizer,使用来构建锁或者其他同步组件的基础框架。

同步器主要通过操作3个方法来对同步状态进行更改,getState(),setState(int newState),compareAndSet(int expected,intupdate)。这些方法能都保证状态的改变是安全的。

同步器是实现锁(或任何其他同步组件)的关键,通常在锁的实现中聚合同步器,利用同步器来实现锁的语义。同步器简化了锁的实现,屏蔽了同步状态管理,线程的排队,等待与唤醒等底层操作。

5.2.1 队列同步器的接口与示例

(1)队列同步器是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方法。

同步器可重写的方法如下

(1)protected boolean tryAcquire(int arg):独占式的获取同步状态,实现该方法需要判断同步状态是否符合预期,然后进行CAS设置同步状态。

(2)protected boolean tryRelease(int arg):独占式释放同步状态,等待获取同步状态的线程将有机会获取同步状态。

(3)protected boolean tryAcquireShared(int arg):共享式获取同步状态,返回大于0的值,表示获取成功,反之,获取失败。

(4)protected boolean tryReleaseShared(int arg):共享式释放同步状态

(5)protected boolean isHeldExclusively():是否被当前线程独占

同步器提供的模板方法:

(1)void acquire(int arg):独占式获取同步状态,如果当前线程获取同步状态成功,则由该方法返回,否则,线程进入同步队列等待,该方法会调用重写的tryAcquire方法。

(2)void acquireInterruptibly(int arg):与acquire(int arg)相同,但是该方法能够响应中断,如果当前线程被中断,则该方法会抛出InterruptedException并返回。

(3)boolean tryAcquireNanos(int arg,long nanos):在acquireInterruptibly(int arg)的基础上增加了超时限制,如果当前线程在超时时间内没有获取到同步状态,那么将返回false,否则返回true。

(4)boolean release(int arg):独占式释放同步状态,该方法会在释放同步状态之后,将同步状态中第一个节点包含的线程唤醒。

(5)Collection<Thread> getQueuedThreads():获取等待在同步队列上的线程集合

同步器提供的方法主要分为3类:独占式获取和释放同步状态共享式获取和释放同步状态查询同步队列中的等待线程情况。


5.3 重入锁

重入锁(ReentrantLock),就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁还支持获取锁时的公平和非公平性选择。

synchronized关键字隐式的支持重进入。

(1)公平锁:如果在绝对时间上,先对锁进行请求的锁先被满足,那么这个锁就是公平的,反之,就是不公平的。公平的获取锁,也就是等待时间最长的线程最优先获得锁,也可以说锁的获取是顺序的。

(2)事实上,公平锁往往没有非公平锁的效率高(公平锁造成大量的线程切换开销),但是,公平锁能够减少“饥饿”发生的概率。

(3)非公平锁虽然可能造成线程饥饿,但极少的线程切换,保证了其更大的吞吐量。

ReentrantLock的实现:

(1)nonfairTryAcquire:判断当前线程是否为获取锁的线程,如果是,则将同步状态的值增加并返回true。

(2)tryRelease:如果该锁被获取了n次,那么前(n-1)次tryRelease方法必须返回flase,而只有同步状态最终被减为0的时候才能返回true。

(3)公平锁的tryAcquire与nonfairTryAcquire唯一的区别就是,判断条件多了hasQueuedPredecessors()方法,即加入了同步队列当前节点是否有前驱节点的判断,如果有的话,tryAcquire会返回false。

nonfairTryAcquire


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

推荐阅读更多精彩内容

  • 5.4 读写锁 之前提到的锁如Mutex和ReentrantLock都是排它锁,这些锁同一时刻都只允许一个线程进行...
    伊凡的一天阅读 539评论 0 1
  • Java并发编程的艺术笔记 1.并发编程的挑战[//www.greatytc.com/p/8c9d063...
    一个秋阅读 514评论 0 0
  • 1.Lock接口 一般来说,一个锁能够防止多个线程同时访问共享资源(但有些锁可以允许多个线程并发的访问共享资源,比...
    加夕阅读 454评论 0 1
  • 主要内容有:Lock接口队列同步器重入锁读写锁LockSupport工具Condition接口 1.Lock接口 ...
    htkeepmoving阅读 254评论 0 1
  • 1.Lock 接口   锁是用来控制多个线程访问共享资源的方式,一般来说, 一个锁能够防止多个线程同时访问共享资源...
    ShayHe阅读 385评论 0 0