[TOC]

事先声明,我只是java并发的新手,这篇文章也只是我阅读《java并发编程的艺术》一书(内容主要涉及前3章)的一些总结和感悟。希望大家能多多讨论,对于错误的地方还请指出。

0. 简介

    程序的世界是有层次分明的,每层都对外封装细节而提供一些方式或者说接口来提供功能,甚至是约束功能来换取正确性等等。那么接下来,就用分层的思想作为灵魂,各种内存模型作为骨架,来简单讨论Java并发的原理。

1. 处理器内存模型

    我们面对的第一个问题是,一个好的处理器要满足什么条件?就像考试的学生一样,当然是做得又快,对得又多。对于处理器来说一般要满足两个条件:
    1. 效率
    2. 正确性
    

1.1 效率

    对于效率来说,处理器提供了很多的机制来满足这一点,并行,指令流水线,指令重排,缓存机制等等。但这些方式必须加以限制来保证正确性,或者说效率和正确性在一定程度上是相互制约的,我们必须加以权衡,合理折中。
    

1.2 正确性

    那么怎么保证正确性呢?同样除了处理器的一些内部的机制,比如禁止某些指令重排,缓存一致性,总线锁,缓存锁定等等,同时还向其上层提供了好的方法,比如说内存屏障,CAS等等,这些方法、机制会让上层(通过合理的方式)更好的来保证程序的正确性,就像Java会提供volatile,synchronized等等方式来让程序员(通过合理的方式)调用保证程序的线程安全。
    让我们更加深入这个话题,一个程序怎么样才叫正确?要满足什么性质?简单来说,有三条性质:
    1. 原子性,就是要么全部做要么全不做,需要硬件的配合,比如CAS。
    2. 可见性,由于缓存的存在,要让一个处理器处理的结果对其他处理器可见,首先要把缓存写入内存。
    3. 顺序性,程序必须保持一定的顺序依次的产生结果。

    注意,处理器的很多机制可以保持其中多种性质,比如内存屏障就可以把缓存刷新进入内存,而其他处理器的缓存无效来保证可见性,和通过禁止指令重排来保证顺序性。比如总线锁,缓存锁定,缓存一致性就通过各种方式来保证顺序性和原子性。
    

2. java内存模型

    好了我们更上一层楼,我们刚刚说在下一层(处理器)提供了各种机制来保证效率和正确性,而这一层正是要使用这些机制来到达这一层,也就是JRE和编译器的正确性和效率。
    JMM(即java内存模型)同处理器模型一样,也有很多的机制,包括各种优化。对外也提供volatile,synchronized和臭名昭著的concurrent包。上层的程序员也要使用(合理的方式)这些Java语言和包来保证线程安全。以下简单叙述一些本层次与上一层次的依赖(注意,synchronized因为JMM的优化可以分为3种)

    1. final域 -> 内存屏障

    2. volatile -> 内存屏障(字节码层次)-> 内存屏障(处理器层次)

    3. synchronized -> 偏向锁 + 轻量级锁 + 互斥锁
    偏向锁 -> CAS
    轻量级锁 -> CAS
    互斥锁 -> moniter -> 原子级处理器指令

    4. concurrent包 -> volatile + CAS

    注意CAS实现concurrent包中的原子操作可能会有三大问题:
    1. ABA问题。(解决办法:在变量前增加版本号)
    2. 循环时间长开销大。(解决办法:pause指令)
    3. 只能保证一个共享变量的原子操作。(解决办法:用锁或着合并操作)

    JMM把各种控制程序顺序性的机制抽象成文字形式,就是happens-before。其目的就是向Java开发者屏蔽特定平台的底层细节,设计的程序只要遵守happens-before就可以保证正确性。

3. 程序员

    这是最上面的层次,简单来说就是来利用好下层提供的机制来更好的编程。我想这也是我们要学习java并发原理的原因。

java并发 - 自底向上的原理分析的更多相关文章

  1. Java并发/多线程-CAS原理分析

    目录 什么是CAS 并发安全问题 举一个典型的例子i++ 如何解决? 底层原理 CAS需要注意的问题 使用限制 ABA 问题 概念 解决方案 高竞争下的开销问题 什么是CAS CAS 即 compar ...

  2. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  3. JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析 http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balaba ...

  4. Java NIO使用及原理分析 (四)

    在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O.通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至 ...

  5. (6)Java数据结构-- 转:JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析  http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balab ...

  6. Java并发-volatile的原理及用法

    Java并发-volatile的原理及用法 volatile属性:可见性.保证有序性.不保证原子性.一.volatile可见性 在Java的内存中所有的变量都存在主内存中,每个线程有单独CPU缓存内存 ...

  7. Java NIO使用及原理分析 (四)(转)

    在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O.通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至 ...

  8. Java并发——volatile的原理

    111 Java并发——volatile的原理

  9. java并发基础及原理

    java并发基础知识导图   一 java线程用法 1.1 线程使用方式 1.1.1 继承Thread类 继承Thread类的方式,无返回值,且由于java不支持多继承,继承Thread类后,无法再继 ...

随机推荐

  1. awk解决实际问题例子

    awk很有用,就不说了,下面记录几个我遇到的例子,汇总 1 获得linux环境变量(ENVIRON) awk 'BEGIN{print ENVIRON["PATH"];}' /et ...

  2. junit断言总结

    我们平时编写自己的测试类,如果没有断言,那么就没写测试的必要了. JUnit框架用一组assert方法封装了最常见的测试任务.这些assert方法可以极大地简化单元测试的编写. Assert类包含了一 ...

  3. PHP的CI框架流程基本熟悉

    CI框架是PHP的一个快速开发框架,我是目前的公司项目后台语言用的PHP,因为我做前端开发,需要用php去填充页面数据,所以就开始去了解这个框架,学习了一些php和数据库的东西,这篇文章先具体介绍CI ...

  4. 小白的.Net Core 2.0 ConsoleApp入门(keng)指南(一)

    一.准备工作 准备工作很简单,甚至可以不用Visual Studio,一只.NET CORE和Runtime即可(你有考虑过世界第一IDE的感受吗) 下载:https://www.microsoft. ...

  5. Java细节

    native关键字用法 native是与C++联合开发的时候用的!java自己开发不用的! 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL, ...

  6. Python之数据结构基础

    一.数据结构基础     a.什么是数据结构          b.数据结构的分类         c.列表           import random from timewrap import ...

  7. Sql2012数据库还原

    Sql2012数据库还原(通过.bak数据库备份文件) 昨天系统挂了,那叫一个悲惨,重装了系统,但是sql2012的数据没有备份,同事帮忙发来备份文件(.bak),开始还原数据. 步骤:1 自己新建一 ...

  8. 汇编语言1(mooc)

  9. stderr,stdout,a.txt缓冲区别

    #include<stdlib.h>#include<stdio.h>#include<string.h>#include<error.h>#inclu ...

  10. javascript 模块

    一.模块 function foo() { var something = "cool"; var another = [1, 2, 3]; function doSomethin ...