java并发有诸多难点,实际上并非java语言本身的问题,本质上说一部分是因为并发操作本身的问题,另外一部分是因为计算机体系结构带来的。为了更好地理解java并发过程中的问题,我们应该对CPU有一些基础的认知。

CPU

在信息时代,CPU是我们耳熟能详的一个概念,大家都知道CPU就是计算机的大脑。计算机中一连串复杂的指令都是由它负责执行的,而这些指令通常就是我们称之为程序的东西。那么CPU到底是什么呢?CPU即中央处理器,它是计算机中控制数据操控的电路。主要由三部分组成:算术/逻辑单元、控制单元、寄存器单元。

控制单元是整个CPU的指挥控制中心,它的主要职责就是协调机器活动,通过向其他两个单元发送控制指令来达到控制效果。算数/逻辑单元主要的职责是负责执行运算,包括算术和逻辑运算,它估计控制单元发送过来的指令执行相应的运算操作。寄存器单元主要的作用是用来临时保存数据,它保存着待处理的或者已经处理的数据,它的出现是为了减少CPU对内存的访问次数,提升读取数据的性能,从而提升CPU的整体工作效率。

cpu与内存的协作

CPU中的寄存器分为通用寄存器和专用寄存器,通用寄存器用于临时存放CPU正在使用的数据,而专用寄存器用于CPU专有用途,比如指令寄存器和程序计数器。CPU与主存通过总线进行通信,CPU通过控制单元能够操作主存中的数据。

-执行两个数值相加的大致过程为:从主存读取第一个操作数放到寄存器A->从主存读取第二个操作数放到寄存器B->两个寄存器保存的值作为输入送入到加法电路->将加法结果保存到寄存器C->控制单元将结果放入主存中。

程序等于数据

原始的计算机并不像现代计算机一样将程序保存起来,以前的人们只对数据进行保存,而设备执行的步骤作为计算机的一部分而被内置在控制单元中。这样就很不灵活,最多通过重新布线来提升灵活性。将程序和数据视作相同本质是很大的计算机思维的突破,因为人们一直认为它们是不同的事物,数据应该存放在主存中而程序应该属于CPU的一部分。

将程序作为数据一样保存在主存中大有好处,控制单元能够从主存读取程序,然后对它们解码并执行。当我们要修改执行程序时可以在计算机的主存中修改,而不必对CPU更改或者重新布线。

指令系统

程序包含了大量的机器指令,CPU对这些指令进行解码并执行。CPU分为两类体系:精简指令集计算机(RISC)和复杂指令级计算机(CISC)。RISC提供了最小的机器指令集,计算机效率高速度快且制造成本低。而CISC提供了强大丰富的指令集,能更方便实现复杂的软件。

机器指令分为三类:数据传输类、算术/逻辑类、控制类。

数据传输类指令用于将数据从一个地方移动到另一个地方。比如将主存单元的内容加载到寄存器的LOAD指令,反之将寄存器的内容保存到主存的STORE指令。此外,CPU与其他设备(键盘、鼠标、打印机、显示器、磁盘等)进行通信的指令被称为I/O指令。

算术/逻辑类指令用于让控制单元请求在算术/逻辑单元内执行运算。这些运算包括算术、与、或、异或和位移等。

控制类指令用于指导程序执行。比如转移(JUMP)指令,它包括无条件转移和条件转移。

指令寄存器与程序计数器

CPU将主存的指令加载进来解码并执行,其中涉及到两个重要的寄存器:指令寄存器和程序计数器。指令寄存器用于存储正在执行的指令,而程序计数器则保持下一个待执行的指令地址。

CPU向主存请求加载程序计数器指定的地址的指令,将其存放到指令寄存器中,加载后将程序计数器的值加2(加入指令长度为2个字节)。

指令如何执行

比如我们要计算11+22,假设过程为:将主存地址为00的内容加载到寄存器A中->将主存地址为01的内容加载到寄存器B中->将寄存器A和寄存器B的数据相加并将结果保存到寄存器C->将寄存器C的结果保存到主存地址为02的位置->end。

这个过程CPU涉及到四个操作:加载(LOAD)、存储(STORE)、加法(ADD)和停止(HALT)。可以对这些操作进行编码,比如可以分别用1、2、3、0000表示。

控制器

CPU与其他设备的通信一般通过控制器来实现,控制器可能在主板上,也可能以电路板形式插到主板。控制器本身可以看成是小型计算机,也有自己简单的CPU。以前每连接一种外设都需要购买相应的控制器,而现在随着通用串行总线(USB)称为通用的标准,很多外设都可以直接用USB控制器作为通信接口。每个控制器都连接在总线上,通过总线进行通信。

每个控制器可能被设计成对应一组地址引用,主存则会忽略这些地址引用。当CPU往这些地址发送消息时,其实是直接穿过主存而到控制器的,操作的是控制器而非主存。这种模式称为存储映射输入/输出。此外,这种模式的另一种实现可以在机器指令中提供特定的操作码,专门用于与控制器通信,这样的操作码称为I/O指令。

直接存储器存取

直接存储器存取(DMA)是一种提升外设通信性能的措施,CPU并非总是需要使用总线,在总线空闲的时间里控制器能够充分利用起来。因为控制器都与总线相连接,而控制器又有执行指令的能力,所以可以将CPU的一些工作分给控制器来完成。比如在磁盘中检索数据时,CPU可以将告知控制器,然后由控制器找到数据并放到主存上,期间CPU可以去执行其他任务。这样可以节省CPU资源。不过DMA会使得总线通信过于复杂,而且会导致总线竞争问题。总线瓶颈源自冯.诺伊曼体系结构。

java并发系列——底层CPU的更多相关文章

  1. Java 并发系列之二:java 并发机制的底层实现原理

    1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...

  2. Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析

    学习Java并发编程不得不去了解一下java.util.concurrent这个包,这个包下面有许多我们经常用到的并发工具类,例如:ReentrantLock, CountDownLatch, Cyc ...

  3. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

  4. Java 并发系列之一

    Java 并发系列之一 简单的总结了一些 Java 常用的集合之后,发现许多集合都针对多线程提供了支持,比如 ConcurrentHashMap 使用分段锁来提高多线程环境下的性能表现与安全表现.所以 ...

  5. Java并发系列[2]----AbstractQueuedSynchronizer源码分析之独占模式

    在上一篇<Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析>中我们介绍了AbstractQueuedSynchronizer基本的一些概 ...

  6. Java并发系列[3]----AbstractQueuedSynchronizer源码分析之共享模式

    通过上一篇的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取.在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快 ...

  7. Java 并发系列之十:java 并发框架(2个)

    1. Fork/Join框架 2. Executor框架 3. ThreadPoolExecutor 4. ScheduledThreadPoolExecutor 5. FutureTask 6. t ...

  8. Java 并发系列之六:java 并发容器(4个)

    1. ConcurrentHashMap 2. ConcurrentLinkedQueue 3. ConcurrentSkipListMap 4. ConcurrentSkipListSet 5. t ...

  9. Java 并发系列之五:java 锁

    1. Lock接口 2. 队列同步器AQS 3. 重入锁 ReentrantLock 4. 读写锁 ReentrantReadWriteLock 5. LockSupport工具 6. Conditi ...

随机推荐

  1. 【SpringBoot】几种定时任务的实现方式

    SpringBoot 几种定时任务的实现方式 Wan QingHua 架构之路  定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java ...

  2. When do we use Initializer List in C++?

    Initializer List is used to initialize data members of a class. The list of members to be initialize ...

  3. java输入/输出流的基本知识

    通过流可以读写文件,流是一组有序列的数据序列,以先进先出方式发送信息的通道. 输入/输出流抽象类有两种:InputStream/OutputStream字节输入流和Reader/Writer字符输入流 ...

  4. 子组件dispatch导致其他页面刷新问题解决

    问题: 现在有一个页面,包含"项目基本要素"和"供应链管控要素"多个组件,其中一个组件有表单级联,通过产品类型的不同选取去调接口获得产品名称的下拉 调接口是通过 ...

  5. 分布式调用链跟踪工具Jaeger?两分钟极速体验

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. 【密码学】AES简单学习

    欧拉函数  公式 φ(n)=(p-1)(q-1) 小于x并且和x互质的数的个数   相关概念 因数:a*b=c 那么就称 a.b 是 c 的因数 素数:一个数如果除了1与它本身之外没有其他的因数,那么 ...

  7. [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行

    [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行 目录 [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行 0x00 摘要 0x0 ...

  8. CF1433A Boring Apartments 题解

    Content 我们把仅由一个或多个相同的数位组成的数字叫作"无聊的数字".我们把 \(\leqslant 10000\) 的这种数字按照以下规则排列: 首先,将仅由 \(1\) ...

  9. java 编程基础 Class对象 反射:动态代理 和AOP:java.lang.reflect.Proxy:(Proxy.newProxyInstance(newProxyInstance​(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h))

    为什么我们使用动态代理 静态代理会让类变多了,多了代理类,工作量变大了,且不易扩展.比如我们上节课的例子,要实现不同的扩展方法就要编写不同的代理类,非常麻烦.   Proxy类的使用规则 Proxy提 ...

  10. vue+uniapp实现美颜拍照录像,相册选择 | 录像限制时长,美颜拍照录像

    一.插件简介 Zhimi-BeautyCamera(智密 - 美颜相机图册插件)是一个支持美颜录像,美颜拍照,选择图视频功能,带录像参数时长限制的uniapp原生插件.平台支持:Android.IOS ...