博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发小结(一) -- 基本概念
阅读量:6570 次
发布时间:2019-06-24

本文共 1537 字,大约阅读时间需要 5 分钟。

hot3.png

这里整理下Java并发中的基本概念,以及个人的理解。

并发与并行

输入图片说明

  • 并行,指的是一个工作者同时做多件事情;并发指的是同一时刻多个工作者做多件事情。
  • 对应到系统,比如说单个CPU,并行就是指单个CPU同时执行多个线程,在同一时间点,只会执行一个线程;并发指的是多个CPU同时执行多个线程。并发一定是并行的,并行的不一定是并发的。

内存可见性

这个概念初看,很容易就产生个疑问:难道内存还有不同见的情况?的确会有,需要了解这个问题,那就需要先了解下Java的内存模型:

输入图片说明

线程、主内存、工作内存之间的关系如上图所示。 工作内存与主内存之间如果不同步,就会造成内存可见性问题: 如果线程A对共享变量X进行了修改,但是线程A没有及时把更新后的值刷入到主内存中,而此时线程B从主内存读取共享变量X的值,所以X的值是原始值,那么我们就说对于线程B来讲,共享变量X的更改对线程B是不可见的。

指令重排序

指令重排序包含两个方面:编译器重排与运行期重排。

  • 编译期重排。编译源代码时,编译器依据对上下文的分析,对指令进行重排序,以之更适合于CPU的并行执行。
  • 运行期重排,CPU在执行过程中,动态分析依赖部件的效能,对指令做重排序优化。

单看指令重排序这个概念,如果没有一定的限制,很明显指令重排序会使程序陷入混乱,没有办法理解,那怎么去限制指令重排序的范围呢,这个就要看下happens-before了。happens-before是在Java内存模型中定义好的, 在以下八种情况下,通过增加内存屏障指令,限制了指令重排序的范围:

  • 同一个线程中的每个Action都happens-before于出现在其后的任何一个Action。
  • 对一个监视器的解锁happens-before于每一个后续对同一个监视器的加锁。
  • 对volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作。
  • Thread.start()的调用会happens-before于启动线程里面的动作。
  • Thread中的所有动作都happens-before于其他线程检查到此线程结束或者Thread.join()中返回或者Thread.isAlive()==false。
  • 一个线程A调用另一个另一个线程B的interrupt()都happens-before于线程A发现B被A中断(B抛出异常或者A检测到B的isInterrupted()或者interrupted())。
  • 一个对象构造函数的结束happens-before与该对象的finalizer的开始
  • 如果A动作happens-before于B动作,而B动作happens-before与C动作,那么A动作happens-before于C动作。

volatile

可以使用volatile变量来解决内存可见性的问题,volatile描述符的主要作用:

  • 保证被volatile修饰的共享gong’x变量对所有线程总数可见的,也就是当一个线程修改了一个被volatile修饰共享变量的值,新值总数可以被其他线程立即得知。
  • 禁止指令重排序优化。
  • 不能保证volatile变量符合操作的原子性。

原子性

这个概念在数据库里也有,一个操作要确保原子性,这个操作不能出现中间状态,要么操作全部成功,要么操作全部失败。比如a++,这个操作实际内部需要“读a->计算a+1->设置a”。要确保这个操作是原子性的,其它线程在对a进行操作时,只能在a++之前或之后对a进行操作,而不能在读 a之后或者设置a之前对a进行操作。

参考文档

  • 《Java并发编程实战》

转载于:https://my.oschina.net/francisxjl/blog/1628850

你可能感兴趣的文章
phpstorm 关闭多余变量提示
查看>>
DOM概述 选取文档元素
查看>>
构建你的第一个Vue.js组件
查看>>
如何完整迁移git仓库到另一个远程地址
查看>>
autocad三维汇报,bim汇报,视图汇报方法
查看>>
来来来,你可能没见过这么全的实战吧
查看>>
【队列源码研究】消息队列beanstalkd源码详解
查看>>
JS基础知识学习(一)
查看>>
多条语音消息合成一整条连续播放与进度条功能技术点!
查看>>
最详细的JavaWeb开发基础之java环境搭建(Windows版)
查看>>
通过btrace排查线上频繁Full GC的case
查看>>
JS基础入门篇(一)
查看>>
JavaScript-包装对象
查看>>
SpringBoot+Mybatis配置Druid多数据源
查看>>
从事GIS开发多年,2017年对GIS行业的心得,尤其对三维GIS的理解
查看>>
golang中数组和slice作为参数的区别
查看>>
Spring Cloud中Hystrix仪表盘与Turbine集群监控
查看>>
从0实现一个tinyredux
查看>>
如何用java完成Excel快速的导入导出
查看>>
从Facebook的React框架事件学习一下开源协议
查看>>