并发编程基础底层原理学习(三) - Sierra、
source link: https://www.cnblogs.com/crstly/p/16331247.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
并发编程基础底层原理学习(三)
线程通信与线程同步
在并发编程中需要解决两个关键问题:1.线程之间如何通信 2.线程之间如何同步。线程通信是指线程之间以何种机制来交换消息。线程之间通信机制有两种:共享内存和消息传递。在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行通信。而在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息进行通信。
线程同步是指程序中用于控制不同线程间操作发生的相对顺序的机制。在共享内存并发模型里,程序员必须显式指定某个方法或某段嗲吗需要在线程之间互斥执行。而在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。
Java内存模型--堆和栈
JVM内部使用的Java内存模型将内存划分为栈和堆,如下图所示。
Java 虚拟机中运行的每个线程都有自己的线程栈。线程栈包含有关线程调用了哪些方法以到达当前执行点的信息。在Java中所有实例域,静态域和数组元素都存储在堆内存中,堆内存在线程之间共享。局部变量,方法定义参数和异常处理器参数不会在线程之间共享,它们不会出现线程安全问题。线程堆栈还包含正在执行的每个方法的所有局部变量(调用堆栈上的所有方法)。一个线程只能访问它自己的线程堆栈。一个线程创建的局部变量对于创建它的线程之外的所有其他线程都是不可见的。即使两个线程正在执行完全相同的代码,这两个线程仍将在各自的线程堆栈中创建该代码的局部变量。因此,每个线程都有自己的每个局部变量版本。所有原始类型的局部变量(boolean、byte、short、char、int、long、float、double)都完全存储在线程堆栈中,因此对其他线程不可见。
Java内存模型抽象结构
Java线程之间的通信由Java内存模型(简称JMM)控制,JMM决定了一个线程对共享变量的写入何时对另一个线程可见。JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。
从上图来看,线程 A 与线程 B 之间如要通信的话,必须要经历下面 2 个步骤:
- 首先,线程 A 把本地内存 A 中更新过的共享变量刷新到主内存中去。
- 然后,线程 B 到主内存中去读取线程 A 之前已更新过的共享变量。
如上图所示,本地内存 A 和 B 有主内存中共享变量 x 的副本。假设初始时,这三个内存中的 x 值都为 0。线程 A 在执行时,把更新后的 x 值(假设值为 1)临时存放在自己的本地内存 A 中。当线程 A 和线程 B 需要通信时,线程 A 首先会把自己本地内存中修改后的 x 值刷新到主内存中,此时主内存中的 x 值变为了 1。随后,线程 B 到主内存中去读取线程 A 更新后的 x 值,此时线程 B 的本地内存的 x 值也变为了 1。
从整体来看,这两个步骤实质上是线程 A 在向线程 B 发送消息,而且这个通信过程必须要经过主内存。JMM 通过控制主内存与每个线程的本地内存之间的交互,来为 java 程序员提供内存可见性保证。
Recommend
-
39
-
41
一、什么是线程 进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程 共享进程的资源 。 操作...
-
31
1. 线程的创建 首先我们来复习我们学习 java 时接触的线程创建,这也是面试的时候喜欢问的,有...
-
7
本书部分摘自《Java 并发编程的艺术》 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JVM 里,JVM 执行字节码,最终需要转化为汇编指令在 CPU...
-
5
synchronized同步关键字简介 synchronized是属于JVM层面的一个关键字,底层是通过一个monitor对象(管程对象)来完成,由于wait()/notify()等方法也依赖于monitor对象,所以只有在同步的块或者方法中才能调用w...
-
2
JUC 并发编程 + 底层原理 注意,一定要是JDK1.8、IDE 一定要设置 1、什么是JUC(重要)
-
3
Go并发编程Golang 通过信道来共享变量的值,避免了直接在不同的线程间共享变量; 在任何时间点只有一个协程有权访问变量的值;在设计上就杜绝了数据竞争的情况。 记住:不要通过共享内存来通信,而应该通过通信来共享内存
-
3
并发编程基础底层原理学习(二) 进程就是应用...
-
4
并发编程基础底层原理学习(四) 在程序执行时,为了提...
-
3
FutureTask的基本介绍FutureTask是Java中的一个类,它实现了Future接口和Runnable接口,并且被用作线程执行的任务。FutureTask可以在多线程环境下异步执行一个任务并获取其结果。FutureTask的特点用法异步执行:通过...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK