Java面试篇基础部分-Java语言中的锁有哪些?

news/2024/9/21 19:24:30/

  Java中的锁主要是用于保障并发线程场景下的数据一致性问题。在多线程编程中为了保证数据一致性,通常需要在使用对象或者方法之前进行加锁操作。也就是说要保证在同一时间内只能由一个线程来对对象进行修改,从而保证了数据一致性,保证了数据安全问题。
在这里插入图片描述
  锁从使用角度上来说可以分为乐观锁和悲观锁,从获取资源的公平性角度上来讲可以分为公平锁和非公平锁,从是否共享资源的角度上来讲可以分为共享锁和独占锁,从锁的状态角度可以分为偏向锁、轻量级锁和重量级锁。

乐观锁

  乐观锁采用了乐观的思想来处理数据,每次读取数据的时候都会认为没有其他人对数据进行修改,所以也就不会上锁,但是在更新的时候会判断是否有人更新过该数据,想要解决这个问题,通常采用的方式就是在写数据的时候先读取出当前的版本号,然后加锁的方式,具体的过程如下

  比较当前版本号与上次的版本号,如果版本号一致,就说明没有更新过,此次就是最新的数据,如果版本号不一致,则进行重复的读写进行比较。

  Java中的乐观锁大部分的场景下是使用CAS(Compare And Swap,比较交换)来实现的,CAS是一种原子更新操作 ,在对数据操作之前首先会比较当前值与传入的值是否一样,如果一样则更新,否则不执行更新操作 ,直接返回失败状态。

悲观锁

  悲观锁采用悲观思想处理数据,也就是说假设在每次读取数据的时候都会认为其他人在修改数据,所以每次在读写数据的时候都会上锁,这样别人想写这个数据的时候就会直接进入到阻塞状态、等待获取到锁。

  Java中的悲观锁大部分的是基于AQS(Abstract Queued Synchronized,抽象的队列同步器)架构来实现。AQS定义了一套多线程访问共享资源的同步架构,许多同步类的实现都依赖于它,例如 Synchroinzed、ReentrantLock、Semaphore、CountDownLatch等等。该框架下的锁首先会尝试一CAS的方式去获取锁,如果获取不到锁,则转换为悲观锁,例如RetreenLock。

自旋锁

  自旋锁:如果持有锁的线程能在很短的时间内释放锁资源,那么这些等待竞争锁的线程就不需要做内核态与用户态之间的切换进入到阻塞、挂起状态,只需要等待一段时间就可以了,也就是自旋。在等待持有锁的线程释放锁之后立即获取到锁,这样就避免了用户线程在内核状态的切换上导致锁的时间消耗。

  线程在自旋时会占用CPU,在线程长时间自旋无法获取到锁,就会导致CPU的浪费,甚至有时线程永远无法获取锁导致CPU资源永远被占用。这个时候就需要设置这个自旋锁的最大自旋时间,有了这个时间以后,如果在这个时间之内没有获取到锁,线程就会退出自旋模式并且释放所持有的锁。

优点

  1、自旋锁在一定程度上减少了CPU上下文之间的切换,可以大幅度的提升锁占用时间短,锁竞争不激烈的代码块的性能。在整个的过程中,CPU耗时是明显少于线程阻塞、挂起、唤醒两次CPU上下文所用的时间。

缺点

  1、如果持有锁的线程占用较长的时间或者获取锁的竞争过于激烈的时候,线程在自旋的过程中会长时间的获取不到资源,导致CPU资源的浪费。所以在有些复杂系统中使用自旋锁的时候要慎重。

  应该如何解决自旋锁的执行时间问题呢?如果自旋锁的执行时间太长了,就会有大量的线程处于自旋状态,占用CPU资源,造成系统资源浪费。所以执行时间的长短设置直接会影响到系统的性能

  JDK在不同的版本中采用了不同的周期,JDK1.5固定DE时间,JDK1.6引入了适应性的自旋锁。适应性的自旋锁自旋时间不是固定的,而是通过上次的时间进行计算得到。可以基本上确定一个线程上下文切换的最佳时间。


http://www.ppmy.cn/news/1528520.html

相关文章

【Linux】简易日志系统

目录 一、概念 二、可变参数 三、日志系统 一、概念 一个正在运行的程序或系统就像一个哑巴,一旦开始运行我们很难知晓其内部的运行状态。 但有时在程序运行过程中,我们想知道其内部不同时刻的运行结果如何,这时一个日志系统可以有效的帮…

RMC语句格式

RMC语句格式举例 在GNSS(全球导航卫星系统)通信中,RMC(Recommended Minimum Specific GNSS Data)语句是一种常用的NMEA 0183格式数据,用于提供关于接收机的定位信息、速度及方向等关键数据。RMC语句特别适…

conda 安装tensorflow一些命令

1、conda env list 查看当前存在的虚拟环境列表 2、conda create -n tensor_py3.7 pip python3.7 第一次安装环境的时候创建,如果有直接第3步,n后边的tensor_py3.7 为虚拟环境名称,可根据自己情况起名, 后边为Python版本号&#…

社团周报系统可行性研究-web后端框架对比-springboot,django,gin

对于目前市面上web后端框架,我主要了解到的就是springboot,django gin等,分别对应java python go三种语言,目前我比较熟悉的就是springboot 目录 spring boot框架 简介 优点 缺点 适用场景 与需求匹配度 django框架 简介…

Ubuntu 与Uboot网络共享资源

1、NFS 1.1 Ubuntu 下 NFS 服务开启 sudo apt-get install nfs-kernel-server rpcbind 等待安装完成,安装完成以后在用户根目录下创建一个名为“Linux”的文件夹,以后所有 的东西都放到这个“Linux”文件夹里面,在“Linux”文件夹里面新建…

HT876 带任意限幅的10.9Wx2高保真音频功放

特点 可任意配置的限幅功能 自由选择音频限制幅度,使输出音频信号限制在固定 失真水平内 内置自动限温控制功能 支持AB类与D类切换 THDN:0.02%(VDD8.4V, RL 4Ω, fIN 1kHz, Po 2x1.0W, BTL) 输出功率(fIN1kHZ,THDN10%) 2x10.9W (VDD9.0V, RL4Ω, BTL) VDD供电范围:2…

用终端请求接口

在终端(命令行界面)中请求接口,通常会使用curl命令,这是一个强大的命令行工具,用于传输数据。curl支持多种协议,包括HTTP、HTTPS、FTP等。下面是一些使用curl在终端中请求HTTP接口的基本示例。 1. 发送GET…

【案例72】Apache检测到目标 URL 存在 http host 头攻击漏洞的解决方案

在网络安全中,我们经常会遇到各种漏洞和攻击,其中 http host 头攻击漏洞是一种比较常见的安全问题。最近,我在处理一个项目时,检测到目标 URL 存在 http host 头攻击漏洞,下面我将分享两种Apache解决这个问题的方法。 …