美文网首页
Java中的各种锁(1)——概述

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

作者: 技术的翅膀 | 来源:发表于2020-12-31 15:09 被阅读0次

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语言实现各种锁的各种方案。

相关文章

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

    1 概述 锁是并发开发中必不可少的,我们在读各种各样的并发开发的文章的时候,都会提到各种各样的锁。因为在并发开发中...

  • Java中各种锁的介绍

    ​ Java中各种锁的介绍 前言 Java提供了各种各样的锁,每种锁...

  • java中各种锁结合源码深度解析

    java中各种锁介绍 1.公平锁 / 非公平锁 公平锁 在java代码中类名是FairSync。 公平锁是指多个线...

  • 偏向锁原理

    1 概述 本文介绍偏向锁相关原理,并不限定于Java中的偏向锁,但是Java中偏向锁的实现也是相同的原理,本文主要...

  • java并发

    1.并发编程中的锁 并发编程中的各种锁java高并发锁的3种实现Java并发机制及锁的实现原理 2.线程池核心线程...

  • Java 中的各种锁

    多线程开发离不开各种锁,下面总结下Java和JDK提供的各种锁机制 synchronized synchroniz...

  • Java中的各种锁

    一个线程中的多个流程能不能获取同一把锁:可重入锁和非可重入锁 可重入锁 可重入性:表明了锁的分配机制,是基于线程的...

  • java中的各种锁

    一. 按照性质 1. 公平锁/非公平锁 公平锁是指等待时间最长的会先获得锁,等待时间短的后获得锁;而非公平锁则不一...

  • java中的各种锁

    懂得 1.公平锁和非公平锁 公平锁是指多个线程在等待同一个锁时,必须按照申请锁的先后顺序来一次获得锁。公平锁的好处...

  • Java中的各种锁

    转自公众号Java建设者 ,作者cxuan Java 锁分类 Java 中的锁有很多,可以按照不同的功能、种类进行...

网友评论

      本文标题:Java中的各种锁(1)——概述

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