Java 中的锁原理、锁优化、CAS、AQS 详解!
来源:jianshu.com/p/e674ee68fd3f
1、为什么要用锁?
锁-是为了解决并发操作引起的脏读、数据不一致的问题。
2、锁实现的基本原理
2.1、volatile
Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁要更加方便。
volatile在多处理器开发中保证了共享变量的“ 可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。

结论:如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。
2.2、synchronized
synchronized通过锁机制实现同步。
先来看下利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。
具体表现为以下3种形式。
对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的Class对象。
对于同步方法块,锁是Synchonized括号里配置的对象。
当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。
2.2.1 synchronized实现原理
synchronized是基于Monitor来实现同步的。
Monitor从两个方面来支持线程之间的同步:
互斥执行
协作
1、Java 使用对象锁 ( 使用 synchronized 获得对象锁 ) 保证工作在共享的数据集上的线程互斥执行。
2、使用 notify/notifyAll/wait 方法来协同不同线程之间的工作。
3、Class和Object都关联了一个Monitor。

Monitor 的工作机理
线程进入同步方法中。
为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner)
拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。
其他线程调用 notify() / notifyAll() 接口唤醒等待集合中的线程,这些等待的线程需要重新获取监视锁后才能执行 wait() 之后的代码。
同步方法执行完毕了,线程退出临界区,并释放监视锁。
参考文档:、锁的使用用例
4.1、ConcurrentHashMap的实现原理及使用


结论:ConcurrentHashMap使用的锁分段技术。首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
原文地址:https://mp.weixin.qq.com/s/3BITJAlZUa2AoVFtcV7xsA
Java 中的锁原理、锁优化、CAS、AQS 详解!的更多相关文章
- 无锁的同步策略——CAS操作详解
目录 1. 从乐观锁和悲观锁谈起 2. CAS详解 2.1 CAS指令 2.3 Java中的CAS指令 2.4 CAS结合失败重试机制进行并发控制 3. CAS操作的优势和劣势 3.1 CAS相比独占 ...
- java中包的命令行(cmd)操作详解
一.什么是包? 为了更好地组织类,防止在一个空间下出现类重名,Java提供了包机制.包是类的容器,用于分隔类名空间(类型于C++中的命名空间).如果没有指定包名,所有的示例都属于一个默认的无名包(又称 ...
- (转)java中静态代码块的用法 static用法详解
一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来 ...
- java中静态代码块的用法 static用法详解(转)
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- 关于Java中的程序,进程和线程的详解...
程序:一段静态的代码,一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体,是应用软件执行的蓝本. 进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个 ...
- 【转】java中静态代码块的用法 static用法详解
原文网址:http://www.cnblogs.com/panjun-Donet/archive/2010/08/10/1796209.html (一)java 静态代码块 静态方法区别一般情况下,如 ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- java中静态代码块的用法 static用法详解
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- [转载] java中静态代码块的用法 static用法详解
一.java 静态代码块 静态方法区别 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- Java中Object.equals和String.equals的区别详解
前言 Java中的堆和常量池的区别是什么呢?Object.equals与String.equals的区别呢?下面让我们通过一个小示例让你明白它- 1.基础知识 Java的存储空间:寄存器.栈.堆.静态 ...
随机推荐
- 认识wsgi
WSGI是什么? WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义 ...
- Vue学习手记03-路由跳转与路由嵌套
1.路由跳转 添加一个LearnVue.vue文件, 在router->index.js中 引入import Learn from '@/components/LearnVue' 在touter ...
- GO --- 将Reader 或者 ReadCloser 转化为 ReadSeeker
原因: ReadSeeker 封装了Seek()方法,这个方法要求资源的任何位置都能被定位,例如存储在磁盘里文件,你可以随时读取文件的任意位置.而response.Body 是通过TCP连接从网络中读 ...
- LTDC/DMA2D——液晶显示
1.显示器的基本参数 (1) 像素像素是组成图像的最基本单元要素,显示器的像素指它成像最小的点. (2) 分辨率一些嵌入式设备的显示器常常以“行像素值 x列像素值”表示屏幕的分辨率.如分辨率 800x ...
- xgboost 源码学习
官方代码结构解析,README.MD XGboost 回归时,损失函数式平方误差损失 分类时,是对数自燃损失: Coding Guide ====== This file is intended to ...
- python 简化数据结构的初始化二 支持关键字参数
1.例子 学自cookbook3
- 浅谈TextView Ellipsize效果与Marquee跑马灯无效果问题
说到TextView 效果,相信大家一定熟悉跑马灯. 先来看看 Ellipsize是什么,Ellipsize 从开发技术上翻译为省略效果.故名思议,就是当文本无法显示全部时,用什么效果来显示未显示的部 ...
- Civil 3D百度云地址
Civil 3D 2018百度云地址 https://pan.baidu.com/s/1edeVhG Civil 3D 2019注册机百度云地址 链接: https://pan.baidu.com/s ...
- ES6深入浅出-2 新版函数:箭头函数 2 视频-2.视频 箭头函数杂谈
杂谈coffeescript 箭头函数抄的是谁? coffeescript 双箭头的形式 箭头函数简洁的语法 数组内每一个值都平方一下 Map的写法 箭头函数的写法 平方后,每一个值再加1 numbe ...
- 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_10-前端显示当前用户-jwt查询接口
定义接口 在api的项目里面定义.AuthControllerApi里面定义接口 jwtResult,里面就有一个jwt的字段. 实现接口 需要这三步 定义私有方法从cookie中读取访问令牌 参数需 ...