Java并发机制的底层实现原理

1.volatile

volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 Lock 前缀,而这个前缀在多核处理器中带来的效果是:

(1)会将处理器缓存行的数据回写到内存中;

(2)同时这个操作会使其它处理器里缓存了这个内存地址的数据无效;

2.synchronized

synchronized是重量级锁,其在JVM实现的原理是基于进入和退出 Monitor 对象来实现同步代码块和方法快。在同步代码块中, moitorenter 指令会插入代码块开始的位置,而 monitorexit 指令会插入在代码块结束位置和异常位置,同时这两个指令必须形成闭环。

对象头

在对象头里面,有一个 Mark Word 内容,用于存储对象的 HashCode  和锁信息。

锁的升级与对比

JDK1.6为了减少获得和释放锁带来的性能消耗,引入了 偏向锁 和 轻量级锁 。锁有四个状态(从低到高): 无锁状态 、 偏向锁状态 、 轻量级锁状态 、 重量级锁状态 。锁的状态只能升级不能降级。

偏向锁

偏向锁是基于大多数情况下,不存在线程对锁的竞争,而且锁总是由同一个线程获得,于是有了偏向锁,用于减少一个线程获得锁的开销。

(1)偏向锁的撤销:

偏向锁会一直等到有线程竞争锁的时候才会撤销,在此之前,都通过对象头 Mark Word 里锁信息指向的线程ID来进行获得锁的操作。

(2)偏向锁的关闭:

偏向锁是默认开启的,如果程序中存在较多的线程对锁的竞争,那么可以在JVM配置 -XX:-UseBiasedLocking=false 来关闭偏向锁,否则偏向锁的撤销过程会有性能的消耗。

轻量级锁

(1)轻量级锁加锁:

线程获得锁的时候,会在线程的栈帧分配空间,然后将锁对象的 Mark Word 信息复制过来,然后线程使用CAS将对象头的 Mark Word替换为指向锁的指针。如果失败,表明其它锁竞争锁,则当前线程尝试自旋获得锁;

(2)轻量级锁解锁:

解锁的时候会将栈帧里的 Mark Word 信息使用CAS复制回对象头中,如果成功,则没有线程的竞争,如果失败,则有线程竞争会导致锁膨胀成重量级锁。

3.原子操作的实现原理

原子:不可被进一步分割的原子;原子操作:不可被中断的一个或一系列的操作;

处理器实现原子操作

(1)总线锁保证原子性:

当一个处理器操作一个数据时,总线锁锁住之后,其它处理器就不能操作这个数据了,其它处理器的操作会被阻塞住。

(2)缓存锁保证原子性:

正是因为总线锁会阻塞内存和CPU之间的通信,开销较大,所以有了缓存锁。一个处理器操作一个缓存行里的数据时,缓存锁会锁定这个数据的内存地址,只能由这个处理器进行操作,其它处理器的操作则会无效。

Java实现原子操作

(1)使用CAS算法, compareAndSwap ,比较并替换;

Java提供了并发包里的 AtomicInteger 、 AtomicBoolean 、 AtomicLong 等等类来实现对应基本变量的原子操作;

(2)CAS实现原子操作的三大问题:

  ①ABA问题:如果仅仅通过判断value是否一致来进行修改,那么可能出现两次修改之后回到原始值的情况,于是添加了版本号就行双重判断;

  ②循环时间开销大:CAS自旋会一直循环,此操作会给CPU带来一定的开销,如果JVM可以支持处理器提供的 pause 指令的话,那就可以进行一定的程度上效率的提升;

  ③只能保证一个共享变量的原子操作:如果需要对多个共享变量进行原子操作,那么可以使用Java并发包提供的 AtomicRefrence 类来实现多个共享变量的原子操作;

(3)使用上锁的机制来实现原子操作,而除了偏向锁之外,其它锁都是通过CAS自旋的方式来获得锁;

《Java并发编程的艺术》Java并发机制的底层实现原理(二)的更多相关文章

  1. JAVA并发编程的艺术 Java并发容器和框架

    ConcurrentHashMap ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成. 一个ConcurrentHashMap里包含一个Segment数组, ...

  2. Java并发编程的艺术(一)——并发编程需要注意的问题

    并发是为了提升程序的执行速度,但并不是多线程一定比单线程高效,而且并发编程容易出错.若要实现正确且高效的并发,就要在开发过程中时刻注意以下三个问题: 上下文切换 死锁 资源限制 接下来会逐一分析这三个 ...

  3. 《Java并发编程的艺术》并发编程的挑战(一)

    并发编程的挑战 并发编程的初衷是让程序运行的更快,但是更多的使用多线程真的会让程序变快吗? 1.线程上下文切换 关于线程上下文切换 多个线程在一个处理器里并不是同时进行的,而是非常快速地在线程之间进行 ...

  4. java并发编程系列七:volatile和sinchronized底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  5. 《Java并发编程的艺术》并发编程的基础(四)

    一.线程简介 1.线程的概念 系统运行的最小单元 2.为何使用多线程 更好地利用系统资源(处理器多核心),提高响应速度. 3.线程的状态 NEW(创建状态) RUNABLE(运行状态,系统调度,争抢时 ...

  6. 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理

    二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...

  7. 那些年读过的书《Java并发编程的艺术》一、并发编程的挑战和并发机制的底层实现原理

    一.并发编程的挑战 1.上下文切换 (1)上下文切换的问题 在处理器上提供了强大的并行性就使得程序的并发成为了可能.处理器通过给不同的线程分配不同的时间片以实现线程执行的自动调度和切换,实现了程序并行 ...

  8. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  9. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

随机推荐

  1. 关于 /bin/bash: warning: setlocale: LC_ALL: cannot change locale (en.US_UTF-8) 问题

    亲测可行 中文 # vim /etc/profile.d/locale.sh export LC_CTYPE=zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8 # vim / ...

  2. 用360清理了一下电脑后发现Eclipse软件无法打开

    今天用360安全卫士清理了一下电脑,然后双击Eclipse软件发现不能打开,弹出以下界面: 解决方法如下: 打开计算机-属性-高级系统设置,修改系统变量里变量名为JAVA_HOME.CLASSPATH ...

  3. SQL注入--SQLMap过WAF

    单引号被过滤情况: 空格.等号未被过滤情况: select被过滤情况: 以此类推,当sqlmap注入出现问题时,比如不出数据,就要检查对应的关键词是否被过滤. 比如空格被过滤可以使用space2com ...

  4. 使用memcached遇到的一些问题

    1 .多台服务器时间不统一,引发缓存存取异常. 问题描述: 同一台memcache缓存服务器,比如memcache.server=192.168.88.51:11211   提供缓存服务: 项目部署到 ...

  5. react项目如何修改默认3000端口号

    在运行react项目时,经常会遇到默认的3000端口被占用的情况,此时不想查找哪个程序占用了3000端口,想使用其他端口继续运行. 打开项目中的node_modules文件夹,找到react_scri ...

  6. C# 异步机制

    Delegate.Invoke Delegate.Invoke is used to execute a delegate on the current thread. A delegate is j ...

  7. 《Dare To Dream》第七次作业:团队项目设计完善&编码测试

    任务一:团队项目<软件设计方案说明书>Github链接:https://github.com/Sophur/Team-Project 任务二:项目集成开发环境: (1)JSP技术 JSP( ...

  8. 使用phxpaxos开发过程中遇到的坑

    1. 开启BatchPropose后,状态机使用ExecuteForCheckpoint生成快照要注意: ExecuteForCheckpoint中的InstanceID不能立即持久化. 例如: 当i ...

  9. centos7下部署mariadb+galera数据库高可用集群

    [root@node1 ~]# cat /etc/yum.repos.d/mariadb.repo # MariaDB 10.1 CentOS repository list - created 20 ...

  10. ALV 动态行列

    动态ALV显示的行列,解决部分报表需求. 运行截图如下: 选择屏幕: ALV输出效果1: ALV输出效果2:: ABAP代码: *&------------------------------ ...