浅析Java并发——并发理论

发表于:2020-11-04 09:31  作者:mark-xiang   来源:博客园

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签: 软件开发

  一、如何理解线程安全
  在多线程中稍微不注意就会出现线程安全问题,那么什么是线程安全问题?
  我的认识是。在多线程下代码执行的结果和预期的正确的结果不一致,该代码就是线程不安全的,否则就是线程安全的
  在深入理解Java虚拟机一书中看到的定义时
  当多个线程访问同一个对象时,如果不用考虑这些线程在运行环境下的调度和交替运行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获取正确的结果,那么这个对象时线程的
  在多线程条件下,多个线程肯定会相互协作完成一件事,一般来说就会涉及到多个线程将相互通信告知彼此状态以及当前执行结果等,另外为了性能优化,还会涉及到编辑器指令重排序和处理器指令重排序
  二、并发编程中的主要解决哪两个问题
  1、线程之间如何通信
  通信是指线程之间以何种机制来交换信息,主要有两种:共享内存和消息传递
  2、线程之间如何完成同步(这里的线程指的是并发执行的活动实体)
  Java内存模型是共享内存的并发模型,线程之间主要通过读-写共享变量来完成隐式通信。
  三、JVM中的共享变量和线程独占变量
  共享变量
  在Java中所有实例域,静态域和数组元素都是放在堆内存中(所有线程均可以访问到,是可以共享的)。
  线程独占
  局部变量,方法定义参数和异常处理器参数不会在线程间共享
  共享数据会出现线程安全的问题,而非共享数据不会出现线程安全的问题
  四、描述一下JMM的抽象结构模型
  我们知道CPU的处理速度和主存的读写速度不是一个量级的,为了平衡这种巨大的差距,每个CPU都会有缓存。因此,共享变量会先放在主存中,每个线程都有属于自己的工作内存,并且会把位于主存中的共享变量拷贝到自己的工作内存中,之后读写操作均使用位于工作内存的变量副本,并且在某个时刻将工作内存的变量副本写到主存中去。JMM就从抽象层定义了这种方式,并且JMM决定了一个线程对共享变量的写入何时对其他线程是可见的。
  如图为JMM抽象示意图,线程A和线程B之间要完成通信的话,要经理如下两步:线程A从主内存中将共享变量读入线程A的工作内存后并进行操作,之后将数据重新写会主内存中;线程B从主内存中读取最新的共享变量。
  从横向去看,线程A和线程B好像通过共享变量在进行隐式通信。这其中就有个问题,如果线程A更新后数据并没有及时的写回,而此时线程B读到了过期的数据,这就出现了脏读现象,可以通过同步机制(控制不同线程操作发生的相对顺序)来解决或者通过valatitl关键字是的每次volatitl变量都能够强制刷新到主存,从而对每个线程都是可见的。
  五、由于JMM,多线程情况下可能出现哪些问题
  从上面内存抽象结构来说,可能出现数据脏读的现象,这就是数据可见性的问题。另外,重排序在多线程中不注意的话也容易存在一些问题,比如一个经典的问题DCL(双重检验锁),这就是需要禁止重排序。另外,在多线程下原子操作例如:i++不加注意也容易出现线程安全的问题。
  单总的来说,在多线程开发时需要从原子性、有序性、可见性三个方面进行考虑。
  J.U.C包下的并发工具类和并发容器也是需要花时间去掌握的。

  上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。


评 论

论坛新帖

顶部 底部


建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海信义律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2021, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道