深入理解java虚拟机--线程安全与锁优化

  • 面向过程编程思想和面向对象编程思想
  • java语言中的线程安全
  • 线程安全的实现方法
  • 锁优化

面向过程编程思想和面向对象编程思想

面向过程编程思想:站在计算机的角度,以算法为核心,数据是客体,程序代码处理数据。
面向对象编程思想:站在现实世界的角度,数据和行为视为对象的一部分。

java语言中的线程安全

5类共享数据类别:1.不可变;2.绝对线程安全;3.相对线程安全;4.线程兼容;5.线程对立。

  1. 不可变(final)
    不可变带来的安全性是最简单和最纯粹的。基本数据类型,final关键字修饰;共享数据是一个对象,对象的行为用final修饰。
  2. 绝对线程安全
    定义:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。
  3. 相对线程安全
    单独操作是线程安全的;需要额外的同步手段(特定顺序的连续调用)。
    例子:Vector的get()、remove()、size()等方法;其他类如:HashTable等。
  4. 线程兼容
    本身不是线程安全的;需要正确使用同步手段。
    例子:Vector的get()、remove()、size()等方法;其他类如:ArrayList、HashMap等。
  5. 线程对立
    无论是采取何种同步措施,都无法达到线程安全的。
    例子:Thread类的suspend()和resume();其他类如:System类的setInt()、setOut()和runFinalizersOnExit()等。

线程安全的实现方法

3种实现方法:1.互斥同步;2.非阻塞同步;3.无同步方案。

  1. 互斥同步
    也称阻塞同步;互斥是方法,同步是目的;互斥的实现方式主要有三种:临界区,互斥量,信号量。实现同步手段:synchronized和ReentrantLock。
  • synchronized:原生语法层面的互斥;关键字经过编译后在同步块前后形成monitorenter和monitorexit两个字节码指令,这两字字节码指令都需要一个reference类型的参数来指明要锁定和解锁的对象;如果synchronized修饰的实例方法则去取对应的对象实例,如果修饰的是类方法,则去取Class对象所为锁对象。有两点要注意的:1.synchronized同步块对同一条线程来说是可重入的,不会出现自己把自己锁死的情况;2.同步块在已进入的线程执行完之前,会阻塞后面其他线程的进入。

  • ReentrantLock:API层面的互斥;相对于synchronized来说有三个高级特性:1.等待可中断;2.可实现公平锁;3.锁可以绑定多个条件;

  • synchronized和ReentrantLock吞吐量比较
    jdk1.5版本:ReentrantLock>synchronized;
    jdk1.6后版本:synchronized、ReentrantLock两者持平;

  • 处理问题方式角度:互斥同步是悲观策略。

    阻塞和唤醒一个线程,需要从用户态转换到核心态,消耗性能。

  1. 非阻塞同步
  • 定义

    基于冲突检测的乐观并发策略,先进行操作,如果没有其他线程的竞争共享数据,那操作就是成功了;如果共享数据有争用,产生了冲突,那就再采取其他的补充措施(最常见的补偿措施就是不断的重试,直到成功为止),这种乐观的策略很多实现都不需要把线程挂起。

  • 处理问题方式角度:非阻塞同步是乐观策略。

  • CAS指令
    内存位置(V)、旧的预期值(A)、新值(B);
    CAS指令执行时,当且仅当V符合旧预期值A时,处理器用新值B更新V的值,否则它就不执行更新,但是无论是否更新了V的值,都会返回V的旧值,上述的处理过程是一个原子操作。

    CAS漏铜,ABA问题:
    如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说它的值没有被其他线程改变过了吗?如果在这段期间它的值曾经被改成了B,后来又被改成了A,那CAS操作就会误认为它从来没有被改变过。

  1. 无同步方案

    2类:1.可重入代码;2.线程本地存储。

    1. 可重入代码
      3个特征:不依赖存储在堆上的数据和公用的系统资源、用到的状态量都是由参数传入、不调用非可重入的方法。

    2. 线程本地存储
      例子:生产者-消费者:Web交互模型中的"一个请求对应一个服务器线程"的处理方式。

锁优化

5种锁优化:1.自旋锁和自适应自旋;2.锁消除;3.锁粗化;4.轻量级锁;5.偏向锁。

  1. 自旋锁和自适应自旋
  • 自旋锁定义
    是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁。
  • 自适应自旋定义
    • 自旋的时间不在固定,由前一次在同一个锁上的自旋时间及锁的拥有者的状态决定。
  • 原因
    • 挂起线程和唤醒线程会消耗处理器时间
    • 共享数据的锁定状态很多情况只会持续很短的时间
  1. 锁消除
  • 定义
    指在虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除。
  1. 锁粗化
    范围扩大,如果虚拟机探测到有这样的一串零碎的操作都是对同一个对象加锁,将会把加锁同步的范围扩展(粗化)到整个操作序列的外部,这样只需要加锁一次就可以了。

  2. 轻量级锁

  • 没有多线程的竞争前提下;减少传统的重量级所使用操作系统互斥量产生的性能消耗。
  • Mark Word
  1. 偏向锁
  • 消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。
  • 不用做CAS操作。

深入理解java虚拟机--线程安全与锁优化相关推荐

  1. 由JVM深入了解Java的线程安全与锁优化

    目录 •写在前面 •线程安全 Java语言中的线程安全 线程安全的实现方法 •锁优化 自旋锁与自适应自旋 锁消除 锁粗化 轻量级锁 偏向锁 •写在前面 讲道理,在谈及线程安全以及锁优化之前,需要先搞清 ...

  2. 深入理解java虚拟机(7)---线程安全  锁优化

    关于线程安全的话题,足可以使用一本书来讲解这些东西.<Java Concurrency in Practice> 就是讲解这些的,在这里 主要还是分析JVM中关于线程安全这块的内容. 1. ...

  3. 深入理解Java虚拟机(周志明第三版)- 第十二章:Java内存模型与线程

    系列文章目录 第一章: 走近Java 第二章: Java内存区域与内存溢出异常 第三章: Java垃圾收集器与内存分配策略 并发处理的广泛应用是Amdahl定律代替摩尔定律成为计算机性能发展源动力的根 ...

  4. JAVA好书之《深入理解Java虚拟机》

    最近打算做好现有工作的前提下,扎实一下自己专业的技术知识,并将相关的经典书也记录一下.今天看了一些JVM相关的知识,这里面的经典是<深入理解Java虚拟机>,适合有点基础又想深入理解其中原 ...

  5. 深入理解Java虚拟机-如何利用 JDK 自带的命令行工具监控上百万的高并发的虚拟机性能...

    虚拟机系列文章 深入理解 Java 虚拟机(第一弹) - Java 内存区域透彻分析 深入理解 Java 虚拟机(第二弹) - 常用 vm 参数分析 深入理解 Java 虚拟机-如何利用 Visual ...

  6. 深入理解 Java 虚拟机(第二弹) - 常用 vm 参数分析

    来自:好好学java 话不多说,今天就分析一下一些常用的Java虚拟机的参数设置,以及如何更好的使用! 1 JVM参数简介 首先想说的是其实这些参数我们并不是陌生的,在平时的开发和使用中经常都会遇到, ...

  7. 《深入理解Java虚拟机》笔记6——高效并发

    第五部分 高效并发 第十二章 Java内存模型与线程 并发处理的广泛应用是使得Amdahl定律代替摩尔定律成为计算机性能发展源动力的根本原因,也是人类"压榨"计算机运算能力的最有力 ...

  8. 《深入理解java虚拟机》笔记1——Java内存区域与Java对象

    运行时数据区域 JVM载执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程 ...

  9. 无责任书评:每个Java程序员都应该深入理解Java虚拟机!

    Java这门语言的发展是很有意思的,它不像Python, Ruby 等完全是开源社区驱动,也不像C#,VB.NET主要由微软操刀.它是一个以Oracle(之前是Sun)为主,各大巨头一起参与,一起制定 ...

最新文章

  1. 构建伪Update服务器工具isr-evilgrade
  2. linux modprobe 内核模块加载卸载命令 简介
  3. Ubuntu 12.04自带包安装GLPI IT资产管理软件
  4. 数据绑定以及Container.DataItem几种方式与用法分析 收藏
  5. Flask--SQLAlchemy
  6. python不同曲线设置标签_【图像分类】基于Pascal VOC2012增强数据的多标签图像分类实战...
  7. 超越村后端开发(7:修改完善代码(持续更新))
  8. KL距离-Kullback-Leibler Divergence
  9. 小米笔记本系统win10家庭版升级为企业版(专业版)
  10. 白话区块链 之 14 - ​区块链的技术意义
  11. 调节效应分析时简单斜率图或交互效应图出现负数截距?
  12. feign 实现签名、服务地址动态切换
  13. python怎样用填充颜色_python中如何给图形填充颜色
  14. 小程序picker用法
  15. OPC基本知识介绍——什么是OPC
  16. 这就是传说中的一行代码一句注释?Python每日一练----种花
  17. C中Ascii码对照
  18. 抖音企业号,抖音搜索框SEO优化系统搭建。
  19. 关于对技术群中群友积极参与问答的一点看法
  20. 盗链网站服务器,网站被挂盗链,木马,悬镜服务器卫士解决您的困扰

热门文章

  1. 前端学习(2942):vue的本地注册
  2. [html] html5中的meta标签renderer有什么作用?
  3. 前端学习(2890):如何短时间内实现v-for 模板编译321
  4. 前端学习(1871)vue之电商管理系统电商系统之路由导航守卫控制页面访问权限
  5. 前端学习(1764):前端调试值之性能分析的方法二
  6. 前端学习(1154):常量const02
  7. mybatis学习(42):mybatis的一级缓存
  8. 第一百二十五期:程序员的自我救赎,使用Python开发性格分析工具
  9. 第二十五期:知乎用Go替代Python,说明了啥
  10. STM32F407 CubeMx使用定时器测量信号频率 分辨率0.001Hz