面试连环炮系列(三):synchronized怎么用的
synchronized怎么用的?
用过,synchronized是常用的并发控制关键字,简单的说就是访问加锁。它可以修饰静态方法或者一个类的class对象,这叫类锁;可以修饰普通方法或者代码块,这叫对象锁。synchronized是可重入锁吗?
从互斥锁的设计上来说,当一个线程试图操作一个由其他线程持有的对象锁的资源时,将会处于阻塞状态,但当一个线程再次请求自己持有对象锁的资源时,这种情况属于重入锁,请求将会成功。java中synchronized是基于原子性的内部锁机制,是可重入的。synchronized的实现原理了解过吗?
synchronized使用了monitorenter和monitorexit指令实现同步,这两个指令本质上都是对一个对象的监视器(monitor)进行获取。这个过程是排他的,同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。- 能说说synchronized的锁升级吗?
jdk1.6以后对synchronized的锁进行了优化,锁的级别从低到高逐步升级:无锁->偏向锁->轻量级锁->重量级锁。但是锁的升级是单向的,只能从低到高升级,不会降级。JVM中对象在内存中的布局分为三块区域:对象头、实例变量和填充数据。对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)。Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。- 如果一个线程获得了锁,锁就进入偏向模式,此时Mark Word的结构变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,这样就省去了大量有关锁申请的操作,提高了程序的性能。
- 在锁竞争激烈的场合,每次申请锁的线程都是不相同的,偏向锁就失效了,偏向锁失败后升级为轻量级锁。轻量级锁是相对于使用操作系统互斥量来实现的传统锁而言的,它所适应的场景是线程交替执行同步块,如果存在同一时间访问同一锁的情况,就会膨胀为重量级锁。
- 轻量级锁失败后,还会进行自适应自旋。大多数情况下线程持有锁的时间都不会太长,如果操作系统层面直接挂起,线程之间的切换时需要从用户态转换到核心态,这个状态的转换需要比较长的时间。自旋锁假设在当前的线程很快可以获得锁,虚拟机会让当前线程做50个循环或100循环空循环。在经过若干次循环后,如果得到锁就顺利进入临界区。如果还不能获得锁就会将线程挂起,升级为重量级锁了。注意,JVM还会自动调整自旋次数,这次成功了,下次自旋的次数会多;如果失败了,下次自旋的次数就会减少。
参考文章:
https://blog.csdn.net/u011212394/article/details/82228321
https://www.cnblogs.com/fuly550871915/p/4890753.html
https://www.cnblogs.com/paddix/p/5405678.html
鸡汤:不要因为走得太远,忘了我们为什么出发。— 纪伯伦
面试连环炮系列(三):synchronized怎么用的的更多相关文章
- 面试连环炮系列(四):说说TCP的三次握手过程
说说TCP三次握手的过程? 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认. 第二次 ...
- 面试连环炮系列(十五):说说Eureka的高可用方案
说说Eureka的高可用方案 至少3个Eureka实例才能满足高可用,配置方法如下: 准备三个节点node1,node2,node3. 在每个实例的application.xml文件里加入 eurek ...
- 面试连环炮系列(九):为什么ConcurrentHashMap是线程安全的
为什么ConcurrentHashMap是线程安全的 JDK1.7中,ConcurrentHashMap使用的锁分段技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一 ...
- 面试连环炮系列(十):一个线程调用两次start会怎么样
一个线程调用两次start会怎么样 Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常. 谈谈线程的生命周期和状态转移 新 ...
- 面试连环炮系列(六):Dubbo应用为什么要部署Zookeeper
Dubbo应用为什么要部署Zookeeper? Zookeeper用来注册和发现服务,简单说就是提供端注册接口信息到Zookeeper,调用端在Zookeeper上查找接口对应的服务IP和端口.由于Z ...
- 面试连环炮系列(二十三): StringBuffer与StringBuild的区别
StringBuffer与StringBuild的区别 频繁修改字符串时,建议使用StringBuffer和StringBuilder类.StringBuilder相较于StringBuffer有速度 ...
- 面试连环炮系列(二十一):你们的项目怎么使用kafka
你们的项目怎么使用kafka? 我们采用kafka进行日志采集,准确点说是ELK方案,即elasticsearch + logstash + kibana + kafka.通过Spring AOP的方 ...
- 面试连环炮系列(二十):TCP的滑动窗口协议是什么
TCP的滑动窗口协议是什么 滑动窗口协议,用于网络数据传输时的流量控制,以避免拥塞的发生.该协议允许发送方在停止并等待确认前发送多个数据分组.由于发送方不必每发一个分组就停下来等待确认,因此该协议可以 ...
- 面试连环炮系列(十四): HTTP状态码302的跳转逻辑
HTTP状态码302的跳转逻辑 302状态码表示重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地 ...
随机推荐
- 几种常见设计模式在项目中的应用<Singleton、Factory、Strategy>
一.前言 前几天阅读一框架文档,里面有一段这样的描述 “从对象工厂中………” ,促使写下本文.尽管一些模式简单和简单,但是常用.有用. 结合最近一个项目场景回顾一下里面应用到的一些模式<Sing ...
- day20191113笔记
默写:程序=数据结构+操作系统. 一.文件上传 1.导入commons-fileupload.jar commons-io.jar 2.配置 <bean id="multipartRe ...
- Linux命令行初学(一)
linux命令大全:https://www.linuxcool.com/ 大概了解到有哪些命令,如果有需要的话可以在该网站上查询. 另外在实验楼学习了一些基础,该篇博客就此次对linux命令行的学习进 ...
- TensorFlow2.0(11):tf.keras建模三部曲
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- 还在用背单词App?使用Python开发英语单词自测工具,助你逆袭单词王!
学英语广告 最近也许是刚开学的原因,不管是公众号,还是刷抖音,导出都能看到关于学英语.背单词的广告. 不知道现在学生们背单词买的什么辅导材料.反正我们上学那会,<星火阅读>特别的火.记得当 ...
- J.U.C剖析与解读2(AQS的由来)
J.U.C剖析与解读2(AQS的由来) 前言 前面已经通过实现自定义ReentrantLock与自定义ReentrantReadWriteLock,展示了JDK是如何实现独占锁与共享锁的. 那么实际J ...
- luogu P2701 [USACO5.3]巨大的牛棚Big Barn |动态规划
题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的 ...
- Go语言学习之路
我关于Go语言的博客原本发布于我的个人网站:wwww.liwenzhouu.com.但是被某些人抄怕了,没办法只好搬运到博客园. 我的Go语言学习之路 2015年底我因为工作原因接触到了Go语言,那时 ...
- 第3节:Java基础 - 必知必会(上)
第3节:Java基础 - 必知必会(上) 本篇是基础篇的第一小节,我们从最基础的java知识点开始学习.本节涉及的知识点包括面向对象的三大特征:封装,继承和多态,并且对常见且容易混淆的重要概念覆盖和重 ...
- 学好linux必须精通用户管理的章节知识
第12章 Linux中用户知识管理 12.1 系统开机启动流程 12.1.1 centos6系统开机启动流程 12.1.1.1 开机系统流程语言描述 服务器电源开关打开 bios自检 目的:检查硬件是 ...