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. 主流TTLCMOS电平介绍
  2. 1337:【例3-2】单词查找树
  3. tomcat关闭和重启
  4. leetcode207. 课程表(dfs/bfs)
  5. python安装requests模块失败_No module named quot;Cryptoquot;,如何安装Python三方模块Crypto...
  6. 亿级消息系统的核心存储:Tablestore发布Timeline 2.0模型
  7. 计算机桌面设置定时,如何设置可以每月自动变化的日历桌面?
  8. 计算机图形数学知识,平面----计算机图形学的基础几何知识
  9. springboot 多线程_从零开始到架构,800页Java+并发+容器+多线程+高并发+Spring+SpringBoot源码...
  10. JavaWeb的环境配置
  11. php网页怎么和PLC通讯,PLC的通讯与编程
  12. 一图学会配置微信云端店员监控收款回调
  13. Bounds用法参考
  14. [譯 + 更新] 參透 Node 中 exports 的 7 種設計模式
  15. GIS空间分析(二)—— 空间分析的历史与发展
  16. 数十万csdn小白难题:自学软件测试,学到什么程度可以出去找工作啊?京东offer不要了,换字节跳动....
  17. 学python要有多少英语词汇量_学习英语到底多少词汇量够用,1年能学习到1000的词汇量吗?...
  18. 无界——多元合作的发散思维
  19. spring cloud 资源服务器授权配置
  20. 42、我的C#学习笔记8

热门文章

  1. Golang操作mongo中_id与id问题
  2. 如何将 iOS 工程打包速度提升十倍以上
  3. 实变函数自制笔记3:集合的势
  4. 数据挖掘可视化+机器学习初探
  5. 活了20年多了才知道!蜂蜜十大鲜见真相吓掉小命
  6. iOS开发基础-C语言数据类型和运算符
  7. Vuex是什么,为什么用Vuex,怎么用
  8. matlab利用shp文件提取单个或者任意个中国各个省份的降雨
  9. 安利一款软件:可视化磁盘分析(查看磁盘空间被那些文件占据了)
  10. SQL server学习(四)T-SQL编程之事务、索引和视图