Java多线程与锁

article/2025/10/20 21:33:33

前文中,我们已经了解了什么是线程,线程间常用通信方式,线程池以及其相关特性,可以看出锁在多线程环境中充当着重要作用,不管是线程间的数据通信,还是线程间的等待和唤醒,都依赖于锁,那么锁又有哪些特征以及分类呢?下面我们一起详细看下。

公平锁/非公平锁

  • 公平锁:多个线程按照申请锁的顺序来获取锁。
  • 非公平锁:多个线程获取锁的顺序不等于申请锁的顺序,可能造成饥饿现象,即某个线程长时间获取不到锁

我们前文提到的Semaphore信号量就支持公平锁和非公平锁两种形式,可以通过下面构造函数指定使用公平锁还是非公平锁

public Semaphore(int permits, boolean fair)

fair为true时是公平锁,反之为非公平锁,默认构造的Semaphore是非公平锁。

ReentrantLock也支持公平锁和非公平锁两种形式,默认实现是非公平锁,可以通过

public ReentrantLock(boolean fair)

来创建公平锁实现的ReentrantLock对象。

独占锁/共享锁

  • 独占锁:该锁单次只能被一个线程持有,该线程释放后,下个线程才能获取
  • 共享锁:该锁同时可以被多个线程持有

Semaphore其内部实现就是共享锁,ReentrantLock内部实现是独占锁,ReentrantReadWriteLock其内部读锁是共享锁,写锁是独占锁。

乐观锁/悲观锁

  • 乐观锁:乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁(这使得多个任务可以并行的对数据进行操作),只有到数据提交的时候才通过一种机制来验证数据是否存在冲突(一般实现方式是通过加版本号然后进行版本号的对比方式实现),如果存在冲突则提交失败。其本身不存在真实存在的锁对象。
  • 悲观锁:悲观锁是基于一种悲观的态度类来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住,然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作,直到前面一个人把锁释放后下一个人数据加锁才可对数据进行加锁,然后才可以对数据进行操作。

一般情况下,乐观锁通过CAS实现,CAS全称为Compare And Swap,译为对比替换,CAS工作如下图所示:

CAS.drawio

首先比较旧址V1与现在内存中的值事否相等,如果相等则把新值V2写入,如果不等则重新从V同步值到V1,重新计算V2后,再进行V和V1的比较。

从上述逻辑可以看出CAS可以保证变量的原子性,但是普通的CAS也有ABA的问题,所谓ABA问题,指的是先将值修改至A,再将值修改为B,最后再改为A,以银行转账为例,现在银行卡里有100元,此时有A,B,C三方需要对银行卡进行操作,其中A 转出100,B 转出 100 ,C转入100,按CAS实现该逻辑:

  1. 账户余额100,此时A 转出 100,由于网络阻塞,A转出卡住
  2. 账户余额100,B转出100,网络顺畅,转出完成
  3. 此时余额0,随后C转入100,网络顺畅,转出完成
  4. 此时余额100,A唤醒,执行执行转出100,执行完成
  5. 此时余额为0

C转入的100没了,重复扣款了,ABA问题的解决方案就是加上版本号。比如AtomicStampedReference,其就是解决了ABA问题的原子引用类。

比较典型的悲观锁实现有synchronized,Lock等。

可重入锁/非可重入锁

  • 可重入锁:当前线程获得锁后,可在不释放该锁的情况下,再次获取这把锁
  • 非可重入锁:当前线程获得锁后,必须释放锁后才能再次获取

ReentrantLock,synchronized都是可重入锁,可重入锁的好处是可以一定程度上避免死锁,NonReentrantLock是非可重入锁的实现。

自旋锁/适应性自旋锁

阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。

所以我们可以让当前线程等待一下,进而使得线程进入自旋状态,如果在自旋完成后前面锁定同步资源的线程已经释放了锁,那么当前线程就可以不必阻塞而是直接获取同步资源,从而避免切换线程的开销。这就是自旋锁。

而在JDK1.6 中,又引入了适应性自旋锁的,自适应的改变在于自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的持有者状态决定。

锁升级过程

锁升级指的是锁状态从无锁->偏向锁->轻量级锁->重量级锁这一变化过程,锁升级是仅对synchronized而言,synchronized在操作同步资源之前需要给同步资源先加锁,这把锁就是存在Java对象头里的(Java对象头相关知识参见Java对象一节的描述)Mark Word内,通常情况下我们可以将其称之为Monitor锁或对象锁。

synchronized依赖Monitor锁完成线程同步,而Monitor锁底层依赖于Mutex Lock(互斥锁)实现,大家都知道互斥锁是悲观锁,进而对于使用synchronized而言,阻塞或唤醒线程所需系统切换CPU的时间往往比用户代码执行时间还长,为了优化这一现象,JDK 1.6中,在synchronized引入了偏向锁和轻量级锁,进而造就了锁升级过程。

锁升级过程从无锁到重量级锁,其级别依此升高,各个锁状态说明如下:

  • 无锁:当没有线程访问共享资源时,处于无锁状态
  • 偏向锁:当锁处于无锁状态时,有其他线程访问共享资源,则锁升级为偏向锁,将当前线程ID记录在对象头和栈帧中,以后该线程在访问共享资源时,只需比对线程ID即可
  • 轻量级锁:当锁是偏向锁时,如果有另外的线程访问该资源,则偏向锁升级成轻量级锁,其他线程通过自旋方式循环尝试获取锁,不会阻塞,提高性能
  • 重量级锁:当有一个线程持有锁的同时,有多个线程在自旋等待,自旋等待的达到一定时间后,轻量级锁升级成重量级锁,除持有锁的线程外,其他线程阻塞

参考链接

https://tech.meituan.com/2018/11/15/java-lock.html


http://chatgpt.dhexx.cn/article/HYrIZ8MN.shtml

相关文章

JAVA基础-多线程中锁机制

多线程锁 多线程锁机制锁的定义锁的分类公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁 锁的使用AQSAQS框架展示AQS定义两种资源共享方式AQS常用的几种方法(自定义同步器实现时)自定义同步器实现…

多线程系列-Java中的锁(简介)

前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6)、使用场景进行举例,为读者介绍主流锁的知识点,以…

JAVA如何在线程中加锁(四种方法)

JAVA多线程锁 线程的生命周期 ​ 总共六种状态,可归结为五种,线程的最终是死亡,阻塞不是最终状态,只是一个临时状态。只有调用了start方法,线程才进入就绪阶段。 //新生 ​ NEW, //运行​ RUNNABLE, //阻塞​ BLOCKE…

大数据平台_大数据应用场景有哪些

大数据时代的出现,简单的讲是海量数据同完美计算能力结合的结果,确切的说是移动互联网、物联网产生了海量的数据,大数据计算技术完美地解决了海量数据的收集、存储、计算、分析的问题。一些公司也成立了大数据部门,大数据得到了企…

银行业9大数据科学应用案例

在银行业中使用数据科学不仅仅是一种趋势,它已成为保持竞争的必要条件。 银行必须认识到, 大数据技术可以帮助他们有效地集中资源,做出更明智的决策并提高绩效。 以下我们罗列银行业使用的数据科学用例清单, 让您了解如何处理大量数据以及如何有效使用数据。 [TOC] 1 欺诈识…

某银行大数据体系架构设计与演进

近年来,随着大数据与人工智能相关技术的迅速发展,新技术逐步在全社会各行各业得到应用。银行业作为一个高度信息化的行业,首当其冲面临着互联网新技术应用的挑战。民生银行在 2013 年开始布局分布式、大数据及人工智能技术等领域,…

图解大数据 | 大数据生态与应用导论

作者:韩信子[ShowMeAI](https://www.showmeai.tech 教程地址:https://www.showmeai.tech/tutorials/84 本文地址:https://www.showmeai.tech/article-detail/167 声明:版权所有,转载请联系平台与作者并注明出处 收藏S…

大数据应用于生活,目前主要应用在哪些领域?

如果提到“大数据”时,你会想到什么?也许大部分人会联想到庞大的服务器集群;或者联想到销售商提供的一些个性化的推荐和建议。 如今大数据的深度和广度远不止这些,大数据已经在人类社会实践中发挥着巨大的优势,其利用价值也超出我们的想像。…

大数据应用管理模式及内容

通过调研,数据应用管理可总结为分散管理型、职能复用型、集中管理型三种模式,数据应用管理模式中重点关注组织管理、需求管理、建设管理、成果管理四大领域。 (1) 管理模式 分散管理型:各部门分散开展数据应用&#xf…

大数据应用于各个行业,大数据在各行各业的具体应用是什么?

大数据无处不在,大数据应用于各个行业,包括金融、汽车、餐饮、电信、能源、体能和娱乐等在内的社会各行各业都已经融入了大数据的印迹,下面详细介绍一下大数据在各行各业的具体应用。      制造业,利用工业大数据提升制造业水…

大数据应用的重要性体现在方方面面

大数据应用的重要性,自全国提出“数据中国”的概念以来,我们周围默默地在发挥作用的大数据逐渐深入人们的心中,大数据的应用也越来越广泛,具体到金融、汽车、餐饮、电信、能源、体育和娱乐等领域,下面就通过本文&#…

4大案例分析金融机构的大数据应用

就“大数据金融”思维利用而言,国外金融机构有着十足丰富的体现,已经将大数据技术在风险控制、运营管理、销售支持及商业模式创新等领域进行了全面的尝试。 案例一:汇丰银行-风险管理 汇丰银行在防范信用卡和借记卡欺诈的基础上,利…

金融业大数据应用场景

如果能够引入外部数据,还可以进一步加快数据价值的变现。外部数据中比较好的有社交数据、电商交易数据、移动大数据、运营商数据、工商司法数据、公安数据、教育数据和银联交易数据等。 大数据在金融行业的应用范围较广,典型的案例有花旗银行利用 IBM 沃…

【行业|分析】大数据对于银行七大应用

如今,Hadoop几乎存在于各个方面,其通过利用大数据来分析信息和增加竞争力。许多金融机构和公司已经开始使用Hadoop成功地解决问题,即便他们本没有计划这样做。因为如果他们不这样做,就会面临市场份额损失的巨大风险。以下是一些特别有趣且重要的大数据和Hadoop用例。 诈骗侦…

银行大数据风控平台的建设要点与应用

金融行业是经营风险的行业,风险控制能力是金融机构的核心竞争力。通常而言,金融机构一般是通过给客户的信用状况评分来计量贷款违约的可能性,并通过客户的风险水平进行利率定价。 而传统的信用测算主要是利用历史借贷数据和财务数据对借款人的…

浅谈大数据如何应用?

大数据所面临的五大问题中最后一个是大数据应用,也是大数据问题的具象和最终展现形式。如果用更高度的概括来表述大数据的生命周期,可以归纳为:大数据来源大数据技术大数据应用。三者缺一不可、彼此相承,见下图: ** …

银行大数据风控管理针对哪些应用场景?

银行是经营风险的企业,在风险识别、衡量、定价和防范等方面的能力水平,是判断银行是否具备核心竞争力的关键。随着社会信息化、数字化体系建设,银行风险管理也必将迎来“数智化”时代。 其实,银行业务的申请、交易、营销等环节都…

大数据技术在银行业应用中,主要有哪些优势,面临哪些难题?

大数据技术在银行业应用中的主要优势与难题 经济社会的三个重要组成要素:产品、信息、资金渗透于互联网时代的诸多环节,互联网时代的激烈竞争当中,电商、银行、物流三大类别企业代表着三种要素的重要占有者,三者都希望成为主宰着…

大数据技术在银行业中的应用场景,主要有哪些?

2、大数据技术在银行业中的主要应用场景 (一)大数据时代下银行的精准营销 按照单个客户个性化的营销方案和沟通服务体系,金融机构依照信息化技术手段可以建立起精确的营销方案以实现对个人客户的精准营销(PrecisionMarketing)。这种建立在精准定位基础之上的营销活…

PyCharm | 社区版—页面汉化方法

如何不适用汉化包汉化PyCharm? 下图PyCharm版本:2020.3 社区版 主页面 File —> Settings —> plugins—> 输入框输入chinese —> Install —> apple —>Ok 重启软件后