Java中的各种锁(1)——概述

1 概述

锁是并发开发中必不可少的,我们在读各种各样的并发开发的文章的时候,都会提到各种各样的锁。因为在并发开发中,难免会碰到多个并发程序(可以是多个线程,也可以是多个进程)之间竞争临界资源的情况。为了避免多个并发程序同时访问同一个资源带来的问题,就需要用到锁。

我们又各种不同的应用场景,需要不同的锁的特性。对锁的分类也有各种各样的方法,有的是按照特性分,有的是按照设计来分。因此就出现了各种各样的名词。因此在深入了解Java中各种锁的特点、实现,以及应用的场景之前,有必要先对各种名词做一个解释。

1.1 公平锁/非公平锁

公平锁/非公平锁是锁的特性。公平锁指的是各个并发程序得到锁的顺序与它们申请锁的顺序相同,也就是说是大家要排队,先申请的先得到。反之,则是非公平锁。
如果使用非公平锁,可能会出现有些线程一直得不到锁,造成线程饥饿的问题。但是非公平锁也有好处,好处就是吞吐量要大一些。

1.2 独享锁/共享锁

顾名思义,独享锁指的是一把锁只能由一个持有者,共享锁则可以有多个持有者。为什么能够共享还需要锁?因为共享锁也是有限制的,比如只能持有者必须做的是同样的某种操作(例如都是读数据),或者对持有者的数量有限制等等。

独享锁能够更好的保证安全性,而共享锁则可以提供更高的性能。

同时,而已将独享锁与共享锁结合起来使用,比如读写锁。读写锁其实是一个“组合锁”,其中包含了一个读锁和一个写锁。读锁是共享锁,写锁是独享锁。 因此读写锁可以支持“读读”的场景,但是不支持“读写”、“写读”、“写写”的场景。

有时候会将独享锁称为互斥锁。

1.3 乐观锁/悲观锁

悲观锁和乐观锁其实体现了对并发的不同态度。悲观的态度认为:并发大概率是会出现问题的(悲观态度),因此在进行操作之前,就需要先获取锁。乐观的态度认为:并发出现问题的概率是很低的(乐观态度),因此只需要在更新数据的时候,进行尝试(查看在业务处理的过程中,数据是否被其他的程序改变了)。如果没有,则进行正常的更新;如果被修改了,则进行异常处理(报错或者重试,根据具体的业务需求来决定。)

因此,悲观锁适用大多数情况下会写数据的操作,因为这样的场景下出现冲突的可能性要高一些;乐观锁则适用于大多数情况下只是读数据的操作,因为这样的情况下出现冲突的可能性要第一些。

1.4 可重入锁

可重入锁可以比喻为“继承”,当“父程序”(父线程或者外层方法)获取了锁之后,“子程序”(子线程或者内层方法)能够自动获取锁。因此,可重入锁也被称为递归锁。

1.5 分段锁

分段锁其实不是一种锁,而是一种使用锁的方式(或者说是思想)。具体来说,就是将竞争资源由一个整体划分为多个段(Segment),在很多情况下,程序对资源的修改是位于一个或者几个segment中,则只需要将这些segment加锁。那么多个并发程序可以同时修改不同的segment。
分段锁最普遍的应用应该是数据库中的行锁和表锁。当应用程序修改少数几行的时候,就是在这些行上加行锁(一行就相当于一个segment)。当行锁太多时,则升级到表锁。
还有就是Java中的ConcurrentHashMap,也采用了分段锁的方式。

1.6 自旋锁

自旋锁其实也不是锁,而是获取锁的方式。指的是要获取锁的程序在获取锁失败后,并不会进入阻塞状态,而是不断的循环尝试获取锁。
这种方式下,线程不会主动进入休眠状态。优点是一旦锁被其他的程序释放,该线程能够快速获取到锁。但是由于循环尝试需要占用CPU,因此在竞争激烈(同一个CPU上竞争锁的程序过多的时候),总体性能会显著下降。

1.7 偏向锁/轻量锁/重量锁

这些也不是锁,而是某些锁的三种状态。
在Java 6之后,为了提高synchronized关键字修饰的代码的效率,引入了这三种状态。
最开始是偏向锁状态,指的是如果一段同步代码一直被一个线程使用,则该线程能够自动获取锁,降低了获取锁的性能开销。(为什么这里用词改为了“线程”,而不是“程序”?这是因为这3种状态是JVM实现的,在一个JVM种的竞争就是线程之间的竞争)。
如果偏向锁状态下,有另外一个线程访问同步代码,则会升级到轻量锁。这个时候线程要获取锁的时候,会采用自旋锁的方式,不会阻塞等待。(这个时候表明竞争不激烈,采用自旋锁能够提高性能。)
但是,如果一个线程在自旋锁状态种等待的时间过长(例如自旋达到一定的次数),就会进入阻塞状态(长时间获取不到锁,多半说明竞争激烈),锁会升级为重量锁。
注意,上面的这个过程是单向的,也就是说只能升级,不能降级。

1.8 小结

这里介绍了一些锁的基本概念和术语。在实际实现的时候,由于应用场景的不同(例如是单机还是分布式等等),会有各种各样的实现方式。后续的文章中,我们会逐一介绍使用Java语言实现各种锁的各种方案。

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

推荐阅读更多精彩内容