线程

Android中消息机制分析

筅森魡賤 提交于 2020-03-09 09:55:04
本文中的源码基于Android 29; 一、概述 对于Android开发者而言,我们处理异步消息用的最多的也是轻车熟路的一种方式,就是使用Handler进行消息的分发和处理。但是我们在一个页面(Activity 或者 Fragment)中可以直接使用Handler进行消息的分发和处理。实例如下: private Handler mHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { //处理消息 return false; } }); 我们一般在handleMessage()方法里进行消息的处理,同时在需要发送消息的地方使用mHandler.sendEmptyMessage(0)发送消息即可。callback回调是怎么收到消息的呢?同时Handler又是怎么发送消息的呢?我们带着问题看一下源码。 Android开发者们都知道:当APP启动时,会默认产生一个主线程(也就是UI线程),这个线程会关联一个消息队列,然后所有的操作都会被封装成消息后在主线程中处理。那么到底Android中消息机制是什么样子的呢? 对于Android程序而言,运行程序也是需要通过Java中的程序入口开始执行

MySQL的内存都用了哪里

半腔热情 提交于 2020-03-09 09:49:12
InnoDB buffer pool :主要用于缓存InnoDB的表、索引数据。通常缓冲池(buffer pool)的大小设置为服务器系统内存大小的50%~75%。如果系统有大量的内存,可以通过将其分配给多个缓冲池实例(buffer pool instances),来提高并发性。缓冲池不宜设置过小或过大,过小会照成缓冲池里面的页不断进行刷新,过大会因为内存争用导致发生交换(swap)。 MyISAM key buffer :用于缓冲MyISAM表的索引,被所有的线程共享。 内存表 :如果是一个内部使用的临时内存表,当表增大时,会将其转换成磁盘表。如果是由MEMORY引擎创建的表,则不会转换成磁盘表。 MySQL Performance Schema :用于监控mysql的执行性能,随着服务器的实际负载变化,动态分配使用内存。一旦内存被分配,只有在下次服务器重启时才会释放。 客户端连接线程 :每个线程会使用到连接缓冲、结果缓冲和线程堆栈。连接缓冲和结果缓冲会进行动态增长。每个连接线程也会使用内存用于计算语句摘要。 全部线程 :所有的线程共享相同的基础内存。当一个线程不再使用,如果线程没有回到线程缓存里,它分配的内存将会释放。 读取缓冲 :对表进行顺序扫描时,会为其分配一个读取缓冲。 随机读取缓冲 :对数据进行任意顺序读取时,会为其分配一个随机读取缓冲,以防止发生磁盘检索。 连接操作

GPU物理架构

♀尐吖头ヾ 提交于 2020-03-09 09:12:18
目前市场上的 NVIDIA 显卡都是基于 Tesla 架构的,分为 G80 、 G92 、 GT200 三个系列。 Tesla 体系架构是一块具有可扩展处器数量的处理器阵列。每个 GT200 GPU 包含 240 个流处理器( streaming processor,SP ),每 8 个流处理器又组成了一个流多处理器 (streaming multiprocessor,SM) ,因此共有 30 个流多处理器。 GPU 在工作时,工作负载由 PCI-E 总线从 CPU 传入 GPU 显存,按照体系架构的层次自顶向下分发。PCI-E 2.0规范中,每个通道上下行的数据传输速度达到了 5.0Gbit/s ,这样 PCI-E2.0 × 16 插槽能够为上下行数据各提供了 5.0*16Gbit/s=10GB/s 的带宽,故有效带宽为 8GB/s, 而 PCI-E 3.0 规范的上下行数据带宽各为 20GB/s 。但是由于 PCI-E 数据封包的影响,实际可用的带宽大约在 5-6GB/s ( PCI-E 2.0 ×16 )。 在 GT200 架构中,每 3 个 SM 组成一个 TPC ( Thread Processing Cluster ,线程处理器集群),而在 G80 架构中,是两个 SM 组成一个 TPC , G80 里面有 8 个 TPC ,因为 G80 有 128(2*8*8)

线程

痴心易碎 提交于 2020-03-09 08:21:43
一.线程实现方式 1.并发与并行 ======================================================================================================================== 2.进程概念 ========================================================================================================================= 3.线程概念 ==========================================================================================================================4.线程调度 ============================================================================================================= 5.主线程 来源: https://www.cnblogs.com/curedfisher/p/12446623.html

Intel x86_64 Architecture Background 2

纵然是瞬间 提交于 2020-03-09 08:01:00
  这里是在学习Intel x86_64体系架构时学习到的一些概念,记录下来以供日后参考。如果有错的地方,欢迎指正! CPU上下文切换(context switch):    这个概念第一次听到对我来说是完全陌生的,但了解之后发现和老师讲的东西有很多联系。现在 linux 是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要把当前状态保存下来,同时加载下一个任务,这个过程叫做 上下文切换 。时间片轮转的方式,使得多个任务利用一个CPU执行成为可能,但是保存现场和加载现场,也带来了性能消耗。 缓存一致性协议:   在多核系统中,各个核的cache存储相同变量的副本,当一个处理器更新cache中该变量的副本时会造成各个核之间的缓存不一致,这就是缓存一致性问题。我们要保证在一个核的缓存更新时,其他处理器应该知道该变量已更新,即其他处理器中cache的副本也应该更新,需要使用缓存一致性协议。 CPU处理输入输出的简要过程: 进程内存分配映射方式:   通过地址转换单元,让每个设备都像拥有了一块独立的DRAM。地址转换单元将虚拟地址转化为物理地址(页到页的模式)。 地址映射基本思想 页到页的映射 在多个操作系统同时工作下的地址映射 超线程技术:   尽管提高CPU的时钟频率和增加缓存容量后的确可以改善性能,但这样的CPU性能提高在技术上存在较大的难度

Java并发(2)- 聊聊happens-before

。_饼干妹妹 提交于 2020-03-09 08:00:28
引言 上一篇文章聊到了Java内存模型,在其中我们说JMM是建立在happens-before(先行发生)原则之上的。 为什么这么说呢?因为在Java程序的执行过程中,编译器和处理器对我们所写的代码进行了一系列的优化来提高程序的执行效率。这其中就包括对指令的“重排序”。 重排序导致了我们代码并不会按照代码编写顺序来执行,那为什么我们在程序执行后结果没有发生错乱,原因就是Java内存模型遵循happens-before原则。在happens-before规则下,不管程序怎么重排序,执行结果不会发生变化,所以我们不会看到程序结果错乱。 重排序 重排序是什么?通俗点说就是编译器和处理器为了优化程序执行性能对指令的执行顺序做了一定修改。 重排序会发生在程序执行的各个阶段,包括编译器冲排序、指令级并行冲排序和内存系统重排序。这里不具体分析每个重排序的过程,只要知道重排序导致我们的代码并不会按照我们编写的顺序来执行。 在单线程的的执行过程中发生重排序后我们是无法感知的,如下代码所示, int a = 1; //步骤1 int b = 2; //步骤2 int c = a + b; //步骤3 1和2做了重排序并不会影响程序的执行结果,在某些情况下为了优化性能可能会对1和2做重排序。2和3的重排序会影响执行结果,所以编译器和处理器不会对2和3进行重排序。 在多线程中如果没有进行正确的同步

东西有点乱

半世苍凉 提交于 2020-03-09 07:51:08
Java中主要同步机制是关键字synchronized,它提供了一种独占的加锁方式,但同步这个术语还包括volatile类型的变量,显式锁和原子变量。 如果多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。有三种方式可以修复这个问题: 不在线程之间共享该状态变量 将状态变量修改为不可变的变量 在访问状态变量时使用同步 在线程安全类中封装了必要的同步机制,因此客户端无须进一步采取同步机制。 无状态对象一定是线程安全的。 大多数Servlet都是无状态的,从而极大地降低了在实现Servlet线程安全性时的复杂性。只有当Servlet在处理请求时需要保存一些信息,线程安全性才会成为一个问题。 在并发编程中,这种由于不恰当的执行时序而出现不正确的结果是一种非常重要的情况,它有一个正式的名字:竞态条件。 最常见的竞态条件类型就是“先检查后执行”操作,即通过一个可能失效的观测结果来决定下一步的动作。 使用“先检查后执行”的一种常见情况就是延迟初始化。延迟初始化的目的是将对象的初始化操作推迟到实际被使用时才进行,同时要确保只被初始化一次。 为了确保线程安全性,“先检查后执行”(例如延迟初始化)和“读取-修改-写入”(例如递增操作)等操作必须是原子的。我们将“先检查后执行”以及“读取-修改-写入” 等操作统称为复合操作:包含了一组必须以原子方式执行的操作以确保线程安全性。

【JVM.1】java内存区域与内存溢出

你离开我真会死。 提交于 2020-03-09 05:48:09
鲁迅曾说过:Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进来,墙里面的人想出去。 一.虚拟机内存分布 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 1.  程序计数器(Program Counter Register)   程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的 字节码的行号指示器 。    由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。称之为“线程私有”的内存。程序计数器内存区域是虚拟机中唯一没有规定OutOfMemoryError情况的区域。 2.  Java虚拟机栈(Java Virtual Machine Stacks)   java虚拟机也是 线程私有 的,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储 局部变量表、操作数栈、动态链接、方法出口 等信息。   咱们常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。 局部变量表存 放了编译期可知的各种 基本数据类型 (8个基本数据类型)、 对象引用

Java多线程系列--“JUC原子类”02之 AtomicLong原子类

耗尽温柔 提交于 2020-03-09 05:38:33
什么是线程安全? 当多个线程访问某个类时,不管这些的线程的执行顺序如何,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。 哈哈书上的解释,还是翻译过来的,看了半天还是觉得有点奇怪。比如说 “类都能表现出正确的行为” 是毛线意思?在网上搜了一番 "线程安全就是说多线程访问同一代码,不会产生不确定的结果" 这样反而跟容易理解,果然读书要么读原版中文书要么读原版英文书,看英文的翻译版真的是蛋疼无比。说到这里,我以前貌似把多线程及线程安全一个根本性问题搞混淆了: 所谓的多线程是指多个线程跑同一段代码,所以线程安全的概念是针对于这段代码而言的而不是针对线程。 一个 无状态 的Servlet //程序清单2-1 一个无状态的Servelet @ThreadSafe public class StatelessFactorizer implements Servlet{ public void service(ServlerRequest req, ServletResponse resp){ BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); encodeIntoResponse(resp, factors); } }

java虚拟机内存区域详解

拈花ヽ惹草 提交于 2020-03-09 05:31:56
Java虚拟机在执行java程序的过程中,会将它所管理的内存区域划分为若干个不同的数据区域。主要分为以下几个区域: 方法区:和堆一样,为多个线程共享,它用于存储类信息、常量、静态常量和即时编译后的代码等数据。 虚拟机栈:用于存储局部变量、操作栈、动态链接、方法出口等信息。 本地方法栈:本地方法栈和Java虚拟机栈发挥的作用非常相似,主要区别是Java虚拟机栈执行的是Java方法服务,而本地方法栈执行Native方法服务(通常用C编写)。 堆:是被所有线程共享的最大的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。 程序计数器:当前线程所执行的字节码的行号指示器,程序计数器是线程隔离的,每一个线程在工作的时候都有一个独立的计数器。程序计数器的特性 (1)程序计数器具有线程隔离性 (2)程序计数器占用的内存空间非常小,可以忽略不计 (3)程序计数器是java虚拟机规范中唯一一个没有规定任何OutofMemeryError的区域 (4)程序执行的时候,程序计数器是有值的,其记录的是程序正在执行的字节码的地址 (5)执行native本地方法时,程序计数器的值为空。原因是native方法是java通过jni调用本地C/C++库来实现,非java字节码实现,所以无法统计 来源: https://www.cnblogs.com