如何学好java高并发多线程之--1--线程底成如何工作
要需学好java多线程,首先的了解计算下的主要组成,如下图,详细的信息学校教过,没学过的请自己找找资料学习,这里你只要知道安照冯洛伊曼提出的
计算机由5部分组成:
输入,输出,存储,控制,运算
对应下图的
I,O,内存条,PC,ALU
由图可以看出,控制器和运输器都是在
CPU内部:
PC控制器中包含,程序计数器,永远指向下一条被指向的指令的地址和程序寄存器用来存储正在被执行的指令。
一台电脑是可以支持装多个cpu的,有主板的插槽决定。服务器一般都有4个cpu。
一个cup可以有多个核。核又分为物理核核逻辑核。逻辑核是利用超线程技术,让一个核在同一时间可以执行2个线程。
Runtime.getRuntime.availableProcessors()java 中这样获取的是逻辑核数。
一个cup多个核多个cup:
多核CPU和多个CPU的区别主要在于性能和成本,多核CPU性能最好,但成本最高;多CPU成本小,便宜,但性能相对较差。多cup占主板空间,单独的线单独的cup单独的缓存。多核,节约空间,共享缓存L3。缓存的存储可以分为指令存储和数据存储两部分。
任何一家cup厂商在发布产品的时候就会提供一系列的汇编指令 ,cpu看到这些汇编就会把它翻译成二进制。所以我们不用使用二进制进行编码。
MOV
LGDT
LITD
所以一般的编译过程 :
java语言 -> (javac) class文件 -> (虚拟机jit) 汇编语言 - > 二进制代码 -> 传入cup信号输入口
小知识- 电路板的制作,将电路打印在一张纸上,然后贴在将一个镀铜的板子上。放在氧化池子,没有贴纸的部分就镀铜就会被氧化掉了。
CUP 和内存交互:
CUP从内存中获取数据时,最小的一般一次性读取一个缓存行,缓存由最小的存储单位缓存行,一般64kb。
空间局部性原则:
Cup好不容易才和内存进行一次交互,所以当进行一次x=1的数据load的时候会把附近空间的一整块数据都load到cup缓存。
例子: 对于一个Array[1024*1024][6]的数组进行求和,按行加和按列加所用的时间是不一样的,因为按行加的时候,可以一次交互load更多的数据到cup缓存。
时间局部性原则:
一个数据正在被访问,这个数据很有可能再次被访问,所以不会马上把变量移除cup缓存。
CUP内存数据同步八大原则操作:
内核线程模型KLT和用户线程模型ULT
内核线程模型KLT – 线程的创建销毁调用都是有操作系统处理。
用户线程模型ULT – 线程的创建销毁调用由用户自己来管理,这个不能发挥cup多核的优势。
JAVA 使用的KLT 模型。
JVM创建线程的的过程:
-
CUP 从ring3切换到ring0创建线程
-
cup从ring0切换到ring3
-
线程执行JVM程序
-
线程执行完毕,切换到ring0销毁线程
为什么要分 用户空间,内核空间 ?
– 保护你的系统,让用户软件不能修改系统信息。
用户态,内核态 :
当一个进程在执行用户自己的代码时处于用户运行态(用户态)
当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),如果要执行文件操作、网络数据发送等操作必须通过write、send等系统调用,这些系统调用会调用内核的代码。
用户态和内核态的切换 :
当在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成一些用户态自己没有特权和能力完成的操作时就会切换到内核态。
上下文切换-
Cup采用时钟片进行线程执行,所以在当前线程时间片用完是需要切换到下一个线程,这时候需要把栈里面的信息进行保存,并把下一个线程的栈信息进行加载。
虚拟机指令级架构:
虚拟机指令级架构分为栈指令级架构和寄存器指令级架构
栈指令级架构 :
cup和内存交互次数多,性能差,可以执行好,JAVA。
寄存器指令级架构:
直接简单讲指令加载到寄存器然后进行计算,性能好可以执行差,Python,Go。
JMM java内存模型
JMM就是对多线程工作进行抽象,形成一个规范,用来适配不同的操作系统,不同的硬件结构,屏蔽不同操作系统和不同硬件细节的差异。
共享变量 – 多个线程共同访问的变量,存在主内存中.
变量副本 – 在线程中将共享变量copy一份副本,复制到工作内存中。