1. synchronized怎么用的?
    用过,synchronized是常用的并发控制关键字,简单的说就是访问加锁。它可以修饰静态方法或者一个类的class对象,这叫类锁;可以修饰普通方法或者代码块,这叫对象锁。

  2. synchronized是可重入锁吗?
    从互斥锁的设计上来说,当一个线程试图操作一个由其他线程持有的对象锁的资源时,将会处于阻塞状态,但当一个线程再次请求自己持有对象锁的资源时,这种情况属于重入锁,请求将会成功。java中synchronized是基于原子性的内部锁机制,是可重入的。

  3. synchronized的实现原理了解过吗?
    synchronized使用了monitorenter和monitorexit指令实现同步,这两个指令本质上都是对一个对象的监视器(monitor)进行获取。这个过程是排他的,同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。

  4. 能说说synchronized的锁升级吗?
    jdk1.6以后对synchronized的锁进行了优化,锁的级别从低到高逐步升级:无锁->偏向锁->轻量级锁->重量级锁。但是锁的升级是单向的,只能从低到高升级,不会降级。JVM中对象在内存中的布局分为三块区域:对象头、实例变量和填充数据。对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)。Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。

    1. 如果一个线程获得了锁,锁就进入偏向模式,此时Mark Word的结构变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,这样就省去了大量有关锁申请的操作,提高了程序的性能。
    2. 在锁竞争激烈的场合,每次申请锁的线程都是不相同的,偏向锁就失效了,偏向锁失败后升级为轻量级锁。轻量级锁是相对于使用操作系统互斥量来实现的传统锁而言的,它所适应的场景是线程交替执行同步块,如果存在同一时间访问同一锁的情况,就会膨胀为重量级锁。
    3. 轻量级锁失败后,还会进行自适应自旋。大多数情况下线程持有锁的时间都不会太长,如果操作系统层面直接挂起,线程之间的切换时需要从用户态转换到核心态,这个状态的转换需要比较长的时间。自旋锁假设在当前的线程很快可以获得锁,虚拟机会让当前线程做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怎么用的的更多相关文章

  1. 面试连环炮系列(四):说说TCP的三次握手过程

    说说TCP三次握手的过程? 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认. 第二次 ...

  2. 面试连环炮系列(十五):说说Eureka的高可用方案

    说说Eureka的高可用方案 至少3个Eureka实例才能满足高可用,配置方法如下: 准备三个节点node1,node2,node3. 在每个实例的application.xml文件里加入 eurek ...

  3. 面试连环炮系列(九):为什么ConcurrentHashMap是线程安全的

    为什么ConcurrentHashMap是线程安全的 JDK1.7中,ConcurrentHashMap使用的锁分段技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一 ...

  4. 面试连环炮系列(十):一个线程调用两次start会怎么样

    一个线程调用两次start会怎么样 Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常. 谈谈线程的生命周期和状态转移 新 ...

  5. 面试连环炮系列(六):Dubbo应用为什么要部署Zookeeper

    Dubbo应用为什么要部署Zookeeper? Zookeeper用来注册和发现服务,简单说就是提供端注册接口信息到Zookeeper,调用端在Zookeeper上查找接口对应的服务IP和端口.由于Z ...

  6. 面试连环炮系列(二十三): StringBuffer与StringBuild的区别

    StringBuffer与StringBuild的区别 频繁修改字符串时,建议使用StringBuffer和StringBuilder类.StringBuilder相较于StringBuffer有速度 ...

  7. 面试连环炮系列(二十一):你们的项目怎么使用kafka

    你们的项目怎么使用kafka? 我们采用kafka进行日志采集,准确点说是ELK方案,即elasticsearch + logstash + kibana + kafka.通过Spring AOP的方 ...

  8. 面试连环炮系列(二十):TCP的滑动窗口协议是什么

    TCP的滑动窗口协议是什么 滑动窗口协议,用于网络数据传输时的流量控制,以避免拥塞的发生.该协议允许发送方在停止并等待确认前发送多个数据分组.由于发送方不必每发一个分组就停下来等待确认,因此该协议可以 ...

  9. 面试连环炮系列(十四): HTTP状态码302的跳转逻辑

    HTTP状态码302的跳转逻辑 302状态码表示重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地 ...

随机推荐

  1. “狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作

    一.垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高. 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介 ...

  2. CCNA 之 八 交换基础 VLAN TRUNK VTP

    交换基础 主要知识点: 二层交换基础 Vlan的概念 Trunk的概念 VTP 二层交换基本配置 首先来看下园区网分层结构 交换机的主要功能: Address learning 学习MAC地址 会维护 ...

  3. Hello! 第一篇博客!

    我在博客园开通博客啦 :) 欢迎大家来关注和玩耍,和我互动, Follow 我! 我关心算法和Python!

  4. 解惑Python模块学习,该如何着手操作...

    Python模块 晚上和朋友聊天,说到公司要求精兵计划,全员都要有编程能力.然后C.Java.Python-对于零基础入门的,当然是选择Python的人较多了.可朋友说他只是看了简单的语法,可pyth ...

  5. 深入比特币原理(四)——锁定脚本(locking script)与解锁脚本(unlocking script)

    通常比特币都是以虚拟货币的概念出现在大众眼前,实际上比特币是第一个真正的区块链"平台",利用它去中心化.不可篡改.可追溯等特点不光可以实现多种交易模式(如点对点交易.多重签名交易等 ...

  6. Python基础之第三方库gevent安装

    安装gevent库: 想要安装gevent库,我们需要确定pip版本: 使用 pip3 list: 我们可以发现pip版本为19.3.1,如果你们的pip版本不是最新版可以使用命令python -m ...

  7. POJ3111

    Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband John got br ...

  8. zabbix系列-Grafana4.6.3+Zabbix 的安装部署

    zabbix系列(五) Grafana4.6.3+Zabbix 的安装部署 伟创享 2019-07-31 11:27:18 使用了一段时间Grafana,感觉还挺好用的.部分效果图如下: ​ zabb ...

  9. WebAPI接口的自动化测试1

    自动化测试要满足四个条件: 1 - 自动化用例能够完成所有测试步骤   -------- postman不支持  没有完整的用例管理系统 2 - 每个用例的输入数据,必须要自动填入  -------- ...

  10. leetcode -- 最长回文子串

    题目: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: ...