Java中 synchronized 关键字的理解
synchronized 关键字的理解
在Java中,synchronized 是一个重量级的控制并发的关键字。
这个关键字可以保证并发过程所必须的“原子性”,“可见性”,“有序性”
一,用法:
在方法内加锁:
synchronized 块在代码编译后生成的字节码中实际上是加上monitorenter 和monitorexit。
//对当前的this对象加锁,和synchronized成员方法是一样的,和synchronized成员方法会互斥,同一时间只能有一个进入。
synchronized (this) {}
//对TestUtil类对象加锁,和静态synchronized方法是一样的,和synchronized静态方法会互斥,同一时间只能有一个进入。
synchronized (TestUtil.class) {}
//对infoVO对象加锁,对某个对象加锁,如果有其他操作这个对象的锁方法,会互斥。
synchronized (infoVO){}
在方法上加锁:
synchronized 方法则是在方法的【flags:】标志上多一个 ACC_SYNCHRONIZED
//对该类的静态方法加锁,多个线程调用同一个类的synchronized静态方法时同一时间只能有一个进入(如果有多个静态方法都是synchronized,也是同一时间只能有一个进入,因为锁针对的是类)。
public synchronized static void staticMethod() {
}//对当前对象的这个成员方法加锁,多个线程调用同一个对象的synchronized成员方法时同一时间只能有一个进入。(如果有多个成员方法都是synchronized,也是同一时间只能有一个进入,因为锁针对的是对象)
public synchronized void simpleMethod() {
}
二,分类
从上面可以看出,synchronized 的加锁分为两类
- 对对象的锁
- 对类的锁
三,锁的优化
synchronized锁是JAVA内置的,jdk对其一直持续优化。
对象头的结构
- 自旋锁
因为java线程映射到内核进程,频繁的线程挂起唤醒对性能造成的影响非常大,所以在jdk1.5之后加入了自旋锁,在等待时间稍短的时候会进行自旋等待,但是自旋会造成cpu的损耗,如果长时间持续自旋仍然拿不到锁,其实对性能反而是种损耗。
使用-XX:+UseSpining开启。自旋次数使用-XX:+PreBlockSpin来更改。
- 轻量级锁
轻量级锁是当请求时,当一个线程来请求锁时,如果同步对象没有被锁定,虚拟机首先将在当前线程的栈帧中建立一个名叫锁记录的空间,用于存储锁对象目前Mark Word的拷贝,然后将对象的Mark Word 更新为这个指针。
如果成功,则获取到了锁,并且对象的MARK Word的锁标志转变为00,变为轻量级锁。如果失败,则判断对象的Mark Word是否已经指向了当前线程的栈帧,如果有则说明已经获取到了锁,正常执行,如果没有,则说明其他线程获取到了这个锁。
如果有两个以上的线程用同一个锁,则轻量级锁会失效,直接膨胀变成重量级锁。标志位变为10
使用了CAS交换Mark Word和栈帧来加锁和解锁
- 偏向锁
偏向锁的偏就是偏心的偏,偏向锁会偏向于第一个获得锁的线程,当第一个线程获取到了锁之后,虚拟机把对象头标志位设为01,偏向模式。用cas操作把线程ID记录在Mark Word中,如果CAS成功,则后续持有偏向锁的这个线程进入时不再需要做任何操作。
而当有另一个线程去尝试获取锁时,则偏向模式结束,撤销偏向恢复到未锁定01或者轻量级锁00。
使用-XX:+UseBisedLocking 来启用。
- 偏向锁和轻量级锁区别
轻量级锁是认为没有竞争,每个线程来的时候不需要阻塞,直接可以通过CAS操作来进行对象锁的更改;而偏向锁则认为锁不会被不同的线程获取(永远只被一个线程使用),所以更暴力,直接连CAS都不做,是这个线程则直接执行,不是这个线程则锁膨胀。
- 重量级锁
在上面的锁的优化都无法解决时,锁会膨胀成重量级锁,重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。
Java中 synchronized 关键字的理解相关推荐
- java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题
先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...
- java中static关键字的理解(转载)
static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键字的用法和平常容易误解的地方,最后列 ...
- 从分布式锁角度理解Java的synchronized关键字
分布式锁 分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备 ...
- java synchronized_Java中synchronized关键字理解
好记性不如烂笔头~~ 并发编程中synchronized关键字的地位很重要,很多人都称它为重量级锁.利用synchronized实现同步的基础:Java中每一个对象都可以作为锁.具体表现为以下三种形式 ...
- java中synchronized的用法详解
记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...
- Java中synchronized和volatile有什么区别?
Java中synchronized和volatile有什么区别? 相关内容 synchronized的问题 什么叫做不完整对象,这个怎么理解呢? 总结 ) 相关内容 1.Java语言为了解决并发编程中 ...
- java中的关键字static
原文链接: https://zhuanlan.zhihu.com/p/70110497 昨晚面试中被问到,没能回答出来.这篇答疑文章写得非常好,无一字可增删,遂直接复制. 在平时开发当中,我们经常会遇 ...
- Java中Synchronized的用法
原文:http://blog.csdn.net/luoweifu/article/details/46613015 <编程思想之多线程与多进程(1)--以操作系统的角度述说线程与进程>一文 ...
- Java中Synchronized的用法(简单介绍)
简单介绍 synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调 ...
最新文章
- 常用10种PHP编辑器下载
- Winform中实现实时颜色拾取器显示RGB和16进制颜色(附代码下载)
- 启明云端分享|SSD20X_烧录mac地址文档参考
- 总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程
- Koa 中间件的执行
- 从资源管理器中,获取被选择的文件的路径(及文件夹)的API
- C#—接口和抽象类的区别?
- 答寒冬的面试题(1)
- 数据库基本----SQL语句大全(转载)
- VirtuoZo数字摄影测量(三)——影像匹配、DEM生成和正射影像拼接
- Scala学习05——Scala集合
- 锐捷客户端linux登录密码忘记,锐捷S3760忘记密码的恢复方法
- 使用Latex排版一篇IEEE Robotics and Automation Letters期刊文章
- Connect Four四子棋c++程序 - 用户交互(1)
- The Little Schemer 笔记(第一章)
- Linux虚拟机CentOS7挂机问题
- ubuntu搜狗输入法
- 操作系统思维导图(一)
- 刚开始学习编程的迷茫、痛苦是必然的?!。
- React----JSX语法
热门文章
- 邯郸学院计算机专业是本科还是专科,邯郸学院是大学吗 是本科还是专科
- linux读写文件实例,Linux在应用层读写寄存器的方法及实现实例
- Spring添加对缓存的支持
- 六十六、实现Vue项目首页轮播图(vue-awesome-swiper)
- 手把手教你插入数学公式,妈妈再也不用担心我写不了论文了
- ICCV 2019 | VrR-VG:聚焦视觉相关关系
- HDU1520 Anniversary party 树形动态规划
- SQL学习---第一章
- 电脑声音推送到手机话筒_一台电脑是不是就能做在线教育直播了?
- 解决Spring Boot 整合Security后,所有接口提示Unauthorized、返回401