带你了解JAVA中的一些锁概念

 更新时间:2021年08月18日 11:16:48   作者:lenlir  
今天小编就为大家分享一篇关于Java分布式锁的概念与实现方式详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

乐观锁和悲观锁

乐观锁:这个锁认为出现锁竞争的概率比较低(当前线程中,线程数量较少,不太涉及竞争,就偶尔竞争一下)

悲观锁:这个所认为出现锁竞争的概率比较大(当前场景中,线程数目比较多,可能涉及竞争)

读写锁

普通的锁提供两个操作:加锁,解锁

读写锁提供三个操作:读加锁,写加锁,解锁。

读加锁和读加锁:不需要互斥

写加锁和写加锁之间:需要互斥

读加锁和写加锁之间:需要互斥

主要适用于读多写少的场景

重量解锁和轻量级锁

从工作量来区分:

重量级锁,工作量更多,消耗资源更多,锁更慢

轻量级锁,工作量更少,消耗资源少,锁更快

操作系统中的mutex就是一个重量级锁(也是悲观锁),这个锁在加锁的时候就会遇到冲突,就会产生内核态和用户态的切换,以及线程的调度和阻塞。

自旋锁

在加锁的时候遇到冲突,不会涉及到用户态和内核态的切换,直接尝试重新获取锁。

会一直在循环中尝试获取锁,直到获取成功,这个过程中没有放弃cpu,不涉及线程调度。

公平锁和非公平锁

在这里插入图片描述

什么叫公平?

就是先来先服务。

如果不是按照先来后到的方式获取锁,就是非公平锁。

可重入锁和不可重入锁

一个线程对于相同的一把锁连续加锁两次。

对于不可重入锁:就会有问题

对于可重入锁:可以充入

例如:我们常用的synchronized就是可重入锁

因为synchronized的底层有一个计数器,当你对同一个对象连续加锁几次后,它的计数器就会加几次,解锁的时候,计数器就会–。

死锁

当产生死锁之后,就无法继续往下工作了(严重BUG)

死锁产生的原因:产生环路等待。

死锁的危害:线程无法继续工作。

避免死锁:1.不要在加锁的代码中在尝试获取其他锁;2.约定一定的顺序获取其他锁。

在这里插入图片描述

CAS(compare and swap)比较并交换

在这里插入图片描述

java中AtomicInteger中的自增方法就可以看出来,如果Var1对象中的值和var2是相等的,就可以将var1的值更新。如果不是,就会一直自旋。

随着CAS的出现就会有ABA问题

什么是ABA问题呢?

举个栗子:ABA问题就是你买了个新手机你不知道这个手机是新机还是翻新机。

画个抽象一点图在解释一下:

在这里插入图片描述

那怎么解决ABA问题呢?

答案是加个版本号!!!

在这里插入图片描述

synchronized的锁升级过程

具体逻辑是这样的:

无锁状态-偏向锁-轻量级锁-重量级锁

第一个线程加锁的时候,并不是真正意义上的加锁,而是设置了一个标记位。

当第二个线程也来访问同一个变量的时候,第一个线程才是真正意义上的加锁,第二个线程也会加锁。这就从偏向锁转向了轻量级锁,随着相乘越来越多,因为轻量级锁内部是自旋锁,多个线程的情况下也不容易立马获取到锁,这时吃cup就越来越严重,慢慢的就转变成了重量级锁,此时没获取到锁的线程转变为内核态,进行阻塞。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • Java的MyBatis框架中MyBatis Generator代码生成器的用法

    Java的MyBatis框架中MyBatis Generator代码生成器的用法

    这篇文章主要介绍了Java的MyBatis框架中Mybatis Generator代码生成器的用法,Mybatis Generator主要被用来生成繁琐的配置文件来提高效率,需要的朋友可以参考下
    2016-04-04
  • Java字符串操作全解析之语法、示例与应用场景分析

    Java字符串操作全解析之语法、示例与应用场景分析

    在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字符串处理技巧,轻松应对笔试面试高频题目,感兴趣的朋友一起看看吧
    2025-04-04
  • Java实现权重随机获取值或对象的方法

    Java实现权重随机获取值或对象的方法

    这篇文章主要介绍了Java实现权重随机获取值或对象的方法,treeMap是一种基于红黑树实现的有序映射表,提供了一系列的方法来操作映射表中的元素,其中tailMap方法是用于返回映射表中大于或等于给定键的部分视图,需要的朋友可以参考下
    2023-11-11
  • 利用java实现二叉搜索树

    利用java实现二叉搜索树

    这篇文章主要介绍了利用java实现二叉搜索树,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • 关于Spring源码是如何解决Bean的循环依赖

    关于Spring源码是如何解决Bean的循环依赖

    这篇文章主要介绍了关于Spring源码是如何解决Bean的循环依赖,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • JavaGUI界面实现页面跳转方法

    JavaGUI界面实现页面跳转方法

    这篇文章主要给大家介绍了关于JavaGUI界面实现页面跳转的相关资料, GUI是指图形用户界面,指采用图形方式显示的计算机操作用户界面,需要的朋友可以参考下
    2023-07-07
  • 浅析Java虚拟机详解之概述、对象生存法则

    浅析Java虚拟机详解之概述、对象生存法则

    这篇文章主要介绍了Java虚拟机详解之概述、对象生存法则,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java并发编程volatile关键字的作用

    Java并发编程volatile关键字的作用

    这篇文章主要介绍了Java并发编程volatile关键字的作用,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • 解决springboot3.2集成mybatis-plus3.5.4.1报错的问题

    解决springboot3.2集成mybatis-plus3.5.4.1报错的问题

    这篇文章给大家介绍了如何解决springboot3.2集成mybatis-plus3.5.4.1报错的问题,文中通过图文介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-12-12
  • 解决java编译错误:程序包不存在的问题

    解决java编译错误:程序包不存在的问题

    出错:Error:(3, 27) java: 程序包com.aliyun.odps.udf不存在,遇到这样的错误问题如何解决呢,下面小编给大家带来了java编译错误:程序包不存在的问题及解决方法,感兴趣的朋友一起看看吧
    2023-05-05

最新评论