写在开头

在上几篇博文中,我们聊到过volatile关键字,用它修饰变量可以保证可见性与有序性,但它并不是锁,在使用时并不会阻塞线程,且不保证原子性,属于一种轻量级、高效的同步方式,因此,如果我们的使用场景仅需要保持可见性或者有序性,那可选择volatile,但如果必须保证原子性的话,volatile就不行了。

在Java多线程中,想真正的保证线程的安全,离不开一个东西,那就是 !我们今天就一起来学习一下Java中的锁,以及常见锁的分类。

认识锁

很多面试官在问到Java锁的时候,往往都会这样开头

同学,你真的了解Java中的锁吗?

在Java中锁是一种非常重要的同步机制,经过前面的学习我们了解到,在并发编程中,经常会遇到多个线程访问同一个共享资源,当多个线程同时对共享资源操作写时,会导致数据不一致。通过锁的同步机制,可以确保在某一时刻只有一个线程能够访问特定的代码块或对象。

Java中实现锁的历程

早在jdk1.5之前就已经引入了synchronized 关键字,这个单词翻译成中文即为“同步”之意, Java 早期版本中,synchronized 属于 重量级锁,效率低下;不过,在 Java 6 之后, synchronized 引入了大量的优化如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销,这些优化让 synchronized 锁的效率提升了很多。JDK 1.5 开始,引入了并发工具包 java.util.concurrent.locks.Lock,让锁的功能更加丰富。

常用的锁

  1. synchronized 关键字锁定代码库
  2. 可重入锁 java.util.concurrent.lock.ReentrantLock
  3. 重复读写锁 java.util.concurrent.lock.ReentrantReadWriteLock

主流锁的分类

现在锁的分类根据不同维度大致分有7类,话不多说,先上一个思维导图便于记忆!

悲观锁 / 乐观锁

悲观锁:一律会对代码块进行加锁,如 synchronized、java.util.concurrent.locks.ReentrantLock;

乐观锁:默认不会进行并发修改,通常采用 CAS 算法不断尝试更新;

适应场景:悲观锁适合写操作较多的场景,乐观锁适合读操作较多的场景

自旋锁

自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环占有、浪费 CPU 资源。

偏向锁 / 轻量级锁 / 重量级锁

JDK 1.5 之后新增锁的升级机制,提升性能。通过 synchronized 加锁后,一段同步代码一直被同一个线程所访问,那么该线程获取的就是偏向锁;偏向锁被一个其他线程访问时,Java 对象的偏向锁就会升级为轻量级锁;再有其他线程会以自旋的形式尝试获取锁,不会阻塞,自旋一定次数仍然未获取到锁,就会膨胀为重量级锁

公平锁 / 非公平锁

公平锁:多个线程按照申请顺序来获取锁。如java.util.concurrent.lock.ReentrantLock.FairSync;

非公平锁:指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程先获得锁。如 synchronized、java.util.concurrent.lock.ReentrantLock.NonfairSync。

可重入锁

指在同一个线程在外层方法获取锁的时候,进入内层方法会自动获取锁。JDK 中基本都是可重入锁,避免死锁的发生。

独享锁 / 共享锁

独享锁指锁一次只能被一个线程所持有。synchronized、java.util.concurrent.locks.ReentrantLock 都是独享锁;

共享锁:指锁可被多个线程所持有。ReadWriteLock 返回的 ReadLock 就是共享锁。

除了以上这6种锁之外,还有的面试题中提到了粗粒度锁与细粒度锁

粗粒度锁 / 细粒度锁

粗粒度锁:就是把执行的代码块都锁定;

细粒度锁:就是锁住尽可能小的代码块,java.util.concurrent.ConcurrentHashMap 中的分段锁就是一种细粒度锁;

粗粒度锁和细粒度锁是相对的,没有什么标准。

总结

OK,今天关于锁的介绍就写到这里啦,本文先做一个总体上的概括,在后续的更新中会做详细介绍呀!

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!

您真的了解Java中的锁吗?这7种不同维度下的锁知道吗?的更多相关文章

  1. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  2. Java中从控制台输入数据的几种常用方法

    Java中从控制台输入数据的几种常用方法 一.使用标准输入串System.in //System.in.read()一次只读入一个字节数据,而我们通常要取得一个字符串或一组数字 //System.in ...

  3. Java中的ReentrantLock和synchronized两种锁定机制的对比

    问题:多个访问线程将需要写入到文件中的数据先保存到一个队列里面,然后由专门的 写出线程负责从队列中取出数据并写入到文件中. http://blog.csdn.net/top_code/article/ ...

  4. Java中Elasticsearch 实现分页方式(三种方式)

    目录 ES 简介 ES 的特点: 一.from + size 浅分页 二.scroll 深分页 scroll删除 三.search_after 深分页 ES 简介 Elasticsearch 是一个基 ...

  5. Java中的ReentrantLock和synchronized两种锁机制的对比

    原文:http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html 多线程和并发性并不是什么新内容,但是 Java 语言设计中的创新之 ...

  6. 你真的了解JAVA中与Webservice相关的规范和实现吗?

    非常多人在项目中使用Webservice,仅仅是知道怎样公布Webservice,怎样调用Webservice,但真要论其来龙去脉,还真不一定清楚. 一切一切还要从我们伟大的sun公司规范说起. JA ...

  7. Java内存管理-你真的理解Java中的数据类型吗(十)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 作为Java程序员,Java 的数据类型这个是一定要知道的! 但是不管是那种数据类型最 ...

  8. 你真的知道Java中boolean类型占用多少个字节吗?

    为什么要问这个问题,首先在Java中定义的八种基本数据类型中,除了其它七种类型都有明确的内存占用字节数外,就boolean类型没有给出具体的占用字节数,因为对虚拟机来说根本就不存在 boolean 这 ...

  9. 你真的理解Java中的try/catch/finally吗?

    看几个例子,回顾一下执行顺序 例子1 无异常,finally中的return会导致提前返回 public static String test() {    try {        System.o ...

  10. 你真的了解JAVA中对象和类、this、super和static关键字吗

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...

随机推荐

  1. Python学习之Pytorch

    一.如何查看本机是否安装了Pytorch 在Python环境中查看是否安装了PyTorch可以通过几个简单的步骤来完成.这里有一些方法: 使用Python命令行: 打开你的命令行工具(比如Termin ...

  2. C++——数据类型笔记

    在C++编程中,了解各类数据类型也是至关重要的.下面我会总结一下C++中的数据类型,包括基本类型,符合类型和自定义类型.方便自己整理和理解. 1,基本类型 C++中的基本类型是构建其他数据类型的基础, ...

  3. 在PWM控制下的直流有刷电机性能优化

    结论 为了避免各位浪费时间, 先说结论: 选择合适的电机驱动模式和PWM频率, 能大幅提升直流电机的性能和可控性, 在常见的48:1减速电机上, 使用慢衰减模式和低于100Hz的PWM频率, 能达到最 ...

  4. 简单了解HTTP、Websocket和Netty

    前言 伴随着网络的快速发展,网络通讯越来越重要,通讯的快捷.安全.方便影响着用户的体验.本文将探讨这些技术的原理.特点以及在实际应用中的应用场景. 1.HTTTP(超文本传输协议) HTTP是一种传输 ...

  5. Rtmp 开发学习

    参考文章:视频传输协议详解(RTMP.RTSP.HLS) RTMP--Real Time Messaging Protocol(实时消息传输协议) RTMP 是由 Adobe 公司提出的,在互联网 T ...

  6. 【开发工具】Linux 服务器 Shell 脚本简单应用(MySql备份等脚本)

    上一章介绍完基础[开发工具]Linux 服务器 Shell 脚本简单入门,这一章结合实际运用 对于 do while if else等流程控制基础不再说明,和编程语言大同小异,可以在实际的脚本使用中学 ...

  7. 新来个架构师,用48张图把OpenFeign原理讲的炉火纯青~~

    大家好,我是三友~~ 在很久之前,我写过两篇关于OpenFeign和Ribbon这两个SpringCloud核心组件架构原理的文章 但是说实话,从我现在的角度来看,这两篇文章的结构和内容其实还可以更加 ...

  8. 【Azure API 管理】讨论APIM是否适合直接存储文件到Azure Storage Account呢?

    问题描述 需要从 APIM 直接将大文件存入Azure Storage,没看到这方面的官方文档,所以是否有这方面的实践案例,或者APIM是否支持引用SDK (如Azure Storage SDK)? ...

  9. Linux上使用CMake简单例子

    记录一下自己简单在linux-Ubuntu上用cmake的例子 首先安装cmake sudo apt install cmake 然后创建一个文件夹,里面放点例子代码 main.cpp //main. ...

  10. C# 课堂管理系统(火影忍者界面!!!)

    1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 usin ...