1.并行和并发

并行:即同时进行,指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。

并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

2.并发的三大特性(可见性、有序性、原子性)

JMM内存模型(JMM内存模型详解)

1.0.可见性

当一个线程修改了共享变量的值,其他线程能够看到修改的值。Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方法来实现可见性的。

1.1.如何保证可见性

通过 volatile 关键字保证可见性。
通过 内存屏障保证可见性。
通过 synchronized 关键字保证可见性。
通过Lock保证可见性。
通过 final 关键字保证可见性

1.2.可见性详解

public class VisibilityTest {private boolean flag = true;public void refresh() {flag = false;System.out.println(Thread.currentThread().getName() + "修改flag");}public void load() {System.out.println(Thread.currentThread().getName() + "开始执行.....");int i = 0;while (flag) {i++;//TODO  业务逻辑}System.out.println(Thread.currentThread().getName() + "跳出循环: i=" + i);}public static void main(String[] args) throws InterruptedException {VisibilityTest test = new VisibilityTest();// 线程threadA模拟数据加载场景Thread threadA = new Thread(() -> test.load(), "threadA");threadA.start();// 让threadA执行一会儿Thread.sleep(1000);// 线程threadB通过flag控制threadA的执行时间Thread threadB = new Thread(() -> test.refresh(), "threadB");threadB.start();}}

JMM的内存可见性保证:

单线程程序:单线程程序不会出现内存可见性问题。编译器、runtime和处理器会共同确保单线程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。

正确同步的多线程程序:正确同步的多线程程序的执行将具有顺序一致性(程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同)。这是JMM关注的重点,JMM通过限制编译器和处理器的重排序来为程序员提供内存可见性保证。

2.0.有序性

程序执行的顺序按照代码的先后顺序执行。JVM 存在指令重排,所以存在有序性问题。

2.1.如何保证有序性

通过 volatile 关键字保证有序性。
通过 内存屏障保证有序性。
通过 synchronized关键字保证有序性。
通过Lock保证有序性。

2.2.有序性详解

    double pi=3.14;//Adouble r=1.0;//Bdouble area=pi*r*r;//C

有序性主要针对的是指令重排,我们需要通过一定的手段来确保程序可控运行。

指令重排:处理器为了提高程序运行效率,可能会对输入代码进行优化,包括处理器重排序和编译器重排序等。当然重排序有一定的原则,遵循as-if-serial的原则

as-if-serial:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial语义。编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。但是,如果操作之间不存在数据依赖关系,这些操作就可能被编译 器和处理器重排序。A和C之间存在数据依赖关系,同时B和C之间也存在数据依赖关系。因此在最终执行的指令序列中,C不能被重排序到A和B的前面(C排到A和B的前面,程序的结果将会被改变)。但A和B之间没有数据依赖关系,编译器和处理器可以重排序A和B之间的执行顺序。

通过上面可以看出没有依赖关系的可能进行指令重排,这种情况下,我们怎么判断是否有数据竞争,是否线程安全呢,这里就依赖happens-before原则,如果不能满足该原则,则有序性不能保证

happens-before定义

  1. 如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作 可见,而且第一个操作的执行顺序排在第二个操作之前。
  2. 两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则 制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果 一致,那么这种重排序并不非法。

happens-before规则
1.程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操 作;
2.锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作;
3.volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
4.传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A 先行发生于操作C;
5.线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
6.线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件 的发生;
7.线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过 Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
8.对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;

我们来分析上面8条规则(摘自《深入理解Java虚拟机第12章》)

程序次序规则:一段代码在单线程中执行的结果是有序的。注意是执行结果,因为虚拟机、处理器会对指令进行重排序。虽然重排序了,但是并不会影响程序的执行结果,所以程序最终执行的结果与顺序执行的结果是一致的。故而这个规则只对单线程有效,在多线程环境下无法保证正确性。
锁定规则:这个规则比较好理解,无论是在单线程环境还是多线程环境,一个锁处于被锁定状态,那么必须先执行unlock操作后面才能进行lock操作。
volatile变量规则:这是一条比较重要的规则,它标志着volatile保证了线程可见性。通俗点讲就是如果一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作一定是 happens-before读操作的。
传递规则:提现了happens-before原则具有传递性,即A happens-before B , B happens- beforeC,那么A happens-before C
线程启动规则:假定线程A在执行过程中,通过执行ThreadB.start()来启动线程B,那么线程A对共享变量的修改在接下来线程B开始执行后确保对线程B可见。
线程终结规则:假定线程A在执行的过程中,通过制定ThreadB.join()等待线程B终止,那么线程B在终止之前对共享变量的修改在线程A等待返回后可见。

引申出的6条规则

1.将一个元素放入一个线程安全的队列的操作Happens-Before从队列中取出这个元素的操作
2.将一个元素放入一个线程安全容器的操作Happens-Before从容器中取出这个元素的操作
3.在CountDownLatch上的倒数操作Happens-Before CountDownLatch#await()操作
4.释放Semaphore许可的操作Happens-Before获得许可操作
5.Future表示的任务的所有操作Happens-Before Future#get()操作
6.向Executor提交一个Runnable或Callable的操作Happens-Before任务开始执行操作

3.0.原子性

一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在 Java中,对基本数据类型的变量的读取和赋值操作是原子性操作(64位处理器)。不采取任何的原子性保障措施的自增操作并不是原子性的。

3.1.如何保证原子性

通过 synchronized 关键字保证原子性。
通过 Lock保证原子性。
通过 CAS保证原子性。

3.2.原子性详解

原子性相对好理解,即要么同时成功要么同时失败,我们通过各种锁机制即可实现,如乐观锁CAS,悲观锁 synchronized和Lock等

并发基础(一)并发的三大特性相关推荐

  1. java三大特性 继承_java基础(二)-----java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  2. CSS基础(复合选择器-三大特性)

    CSS基础(复合选择器-三大特性) Emmet语法 快速生成HTML 如果想快速生成多个标签,直接*n. div*3

  3. 巩固剖析并发基础:并发三大特性详解 代码实例分析可见性问题 深入了解JMM模型

    文章目录 一.并发和并行 二.并发三大特性 2.1 可见性 2.2 有序性 2.3 原子性 三.Java内存模型(JMM) 3.1 JMM定义 3.2 JMM与硬件内存架构的关系 3.3 内存交互操作 ...

  4. 【并发】2、JMM三大特性与Volatile

    JMM三大特性与Volatile 什么是JMM模型 线程,工作内存,主内存工作交互图(基于JMM规范) JVM虚拟机 Java内存模型与硬件内存架构的关系 JMM存在的必要性 数据同步八大原子操作 j ...

  5. css复合选择器和基础选择器、css三大特性

    复合选择器 在css中,复合选择器是建立在基础选择器之上,对基本选择器进行组合形成的. 常用的复合选择器:后代选择器.子选择器.并集选择器.伪类选择器 (1)后代选择器 后代选择器又称为包含选择器,可 ...

  6. java多态基础_java基础(三)-----java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  7. Java并发(一)并发基础

    https://www.cnblogs.com/jinshuai86/p/9226164.html Java编程的逻辑 Java并发编程的艺术 极客时间:Java并发编程实战 Java并发基础知识 并 ...

  8. 【并发编程】并发编程的三大特性

    并发编程的书籍都会讲到并发编程的三大特性,这是并发编程中所有问题的根源,我们只有深刻理解了这三大特性,才不会编写出漏洞百出的并发程序. 基本概念 1.原子性,所有操作要么全部成功,要么全部失败. 2. ...

  9. java 原子类_小学妹教你并发编程的三大特性:原子性、可见性、有序性

    在并发编程中有三个非常重要的特性:原子性.有序性,.可见性,学妹发现你对它们不是很了解,她很着急,因为理解这三个特性对于能够正确地开发高并发程序有很大的帮助,接下来的面试中也极有可能被问到,小学妹就忍 ...

最新文章

  1. 自我总结(四) ---java web项目完结,j2ee的开始
  2. Android性能优化面试题,与性能优化相关面试题 - 与IPC机制相关面试题 - 《Android面试宝典》 - 书栈网 · BookStack...
  3. CentOS自动挂载光驱和U盘
  4. AlphaGo背后的力量:蒙特卡洛树搜索入门指南
  5. python中list怎么用_python中list(列表)的使用方法总结(图文)
  6. 「leetcode」538.把二叉搜索树转换为累加树【递归】【迭代】详解
  7. python 矩阵点乘_Python之Numpy库基础——矩阵运算
  8. matlab plv,脑电脑网络分析代码使用流程介绍
  9. tplink迷你路由器中继模式_TP-link迷你无线路由器Repeater模式(中继模式)设置教程(转载).docx...
  10. 单片机、嵌入式ARM学习网站推荐(多年的积累)
  11. 祝所有的程序猿春节愉快,好好休息
  12. 计算机算法的控制结构顺序结构,第3章 算法与控制结构.pdf
  13. 找寻自己的哲学世界?
  14. 申请上计算机课的申请,诺丁汉大学计算机学院课程申请通道将即将关闭,抓紧上车了...
  15. fastjson转换大全
  16. 下班后我都学了什么 | Python 如何高效的遍历DataFrame?
  17. 给力!安卓和QQ物联课程都发布新章节
  18. 108K加湿器开发方案 芯片制造 NY8A051F 单片机开发设计开发
  19. Altium Designer安装包及安装与破解步骤(初学)
  20. netty应用场景之三点

热门文章

  1. iOS - 避免App界面多点触控
  2. 腾讯、百度、珍爱网、中国电信、三之乐面试经历
  3. ELMO Gold Twitter 使用EAS II配置过程(一)Quick Tuning
  4. 为Python的pip设置多个源
  5. 赠书福利丨你意想不到的个人隐私数据泄露
  6. 数据挖掘基础知识整理
  7. 定时任务Quartz
  8. 构建项目生成的文件(.mvn、mvnw、mvnw.cmd、.gitignore)
  9. Trimble Tekla Structures 2021 SP2
  10. 工创赛基于stm32f103的HAL库的全向麦轮的四个7路寻迹传感器智能款采集程序