线程池
线程池 线程池 Executor 接口: 声明了 execute(Runnable runnable)方法,执行任务代码 ExecutorService 接口: 继承 Executor 接口,声明方法:submit、invokeAll、invokeAny 以及 shutDown 等 AbstractExecutorService 抽象类: 实现 ExecutorService 接口,基本实现 ExecutorService 中声明的所有方法 ScheduledExecutorService 接口: 继承 ExecutorService 接口,声明定时执行任务方法 ThreadPoolExecutor 类: 继承类 AbstractExecutorService,实现 execute、submit、shutdown、shutdownNow 方法 ScheduledThreadPoolExecutor 类: 继承 ThreadPoolExecutor 类,实现 ScheduledExecutorService 接口并实现其中的方法 Executors...
并发处理
并发处理 多线程特性 原子性 一个或多个操作要么全部执行并且执行过程中不会被任何因素打断,要么就不执行。 可见性 当多个线程同时访问一个变量时,一个线程修改了这个变量,其他线程能够立即看见修改的值。单线程不存在可见性问题。 有序型 程序的执行按照代码的先后顺序执行 对象的发布和逸出 发布 "发布( Publish)"一个对象的意思是指,使对象能够在当前作用域之外的代码中使用 一个指向该对象的引用保存到其他代码可以访问的地方 123456789public class Person(){ private String name; private int age;}public class Record{ Person p;} 在某一个非私有的方法中返回该引用 12345678public class Person(){ private String name; private int age; public Person...
线程间通讯
线程间通讯 线程通信 线程间通信常用方式 休眠唤醒 object 的 wait,notify,notifyAll Condition 的 await,signal,signalAll CountDownLatch:用于某个线程 A 等待若干个其他线程执行完之后,它才执行 CountDownLatch 这个类能够使一个线程等待其他线程完成各自的工作后再执行。 CountDownLatch 是通过一个计数器来实现的,计数器的初始值为线程的数量。 每当一个线程完成了自己的任务后,计数器的值就会减 1。当计数器值到达 0 时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。 CyclicBarrier:一组线程等待至某个状态之后再全部同时执行 CyclicBarrier 实现让一组线程等待至某个状态之后再全部同时执行。 CyclicBarrier 底层是 ReentrantLock 和 Condition 实现 Semaphore:用于控制对某组资源的访问权限 Object 和 Condition 休眠唤醒区别 object...
Java虚拟机栈栈帧
Java虚拟机栈栈帧 java虚拟机以方法作为最基本的执行单位。“栈帧”是用于支持虚拟机进行方法调用和方法执行背后的数据结构。栈帧存储了方法的局部变量表,操作数栈,动态链接和方法返回地址等信息。 栈帧的概念结构 局部变量表 局部变量表是一组变量值的存储空间,局部变量表以变量槽为单位 java虚拟机规范中未规定一个变量槽应该占有内存空间大小,只是有导向的说明没个变量槽都应该存放一个boolean,byte,char,short,int,float,reference,returnAddress类型的数据 reference 表示对一个对象的引用,java虚拟机规范中并没有明确指出reference类型的长度。 虚拟机至少通过这个应用确认两件事: 根据引用直接或间接的查找到对象在java堆中的数据存放的起始地址或索引 根据引用直接或间接的查找对象所属数据类型在方法区中的存储的类型信息 returnAddress现在基本很少出现 操作数栈 _ 两个栈帧之间的数据共享 _ 动态链接 方法返回地址 附加信息
垃圾回收和内存分配
垃圾回收和内存分配 垃圾回收 垃圾判别算法 引用计数法 一个对象A,只要有任何一个对象引用了A ,则A 的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A 的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收。 优点 实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。 缺点 需要单独的字段存储计数器,增加了存储空间的开销。 每次赋值伴随着计数器的增减,增加时间开销。 无法处理循环依赖的问题 可达性分析 将对象及其引用关系看作一个图,选定活动的对象作为 GC Roots,然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是不存在引用链条,那么即可认为是可回收对象。 基本思路: 可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。 使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(Reference...
虚拟机运行时数据区域
虚拟机运行时数据区域 运行时数据区域 程序计数器 通过改变这个计数器 的值来选取下一条需要执行的字节码指令 java 虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器只会执行一条线程中的指令,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器。 每个线程都会有属于自己独立的线程计数器,各线程之间计数器不会相互影响,独立存储,这些区域成为线程私有。 Java虚拟机栈 Java方法执行的线程内存模型 每个方法被执行,Java虚拟机栈会创建一个栈帧(1),用于存储局部变量表,操作数栈,方法出口,动态链接等信息。 一个方法的执行对应着一个栈帧的入栈与出栈过程。 局部变量存储存放编译期间可知java虚拟机的基础类型(boolean,byte,char、short、int、float、dubbo、long)、对象引用(reference类型)、和returnAddress类型(指向一条字节码指令的地址)。 局部变量表的存储单位是局部变量槽(slot) 其中64位长度的long和...
JVM
JVM GC评估标准 吞吐量 CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。 吞吐量就是比如:虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。 这种情况下,应用程序能容忍较高的暂停时间。因此,高吞吐量的应用程序有更长的时间基准,快速响应是不必考虑的。 吞吐量优先,意味着在单位时间内,STW的时间最短:0.2 + 0.2 = 0.4 暂停时间 指一个时间段内应用程序线程暂停,让GC线程执行的状态 GC期间100毫秒的暂停时间意味着在这100毫秒期间内没有应用程序线程是活动的。 暂停时间优先,意味着尽可能让单次STW的时间最短 为何永久代被元空间替代 永久代有固定上限,无法进行调整,而元空间直接使用内存,受本机可用内存限制。 元空间里存放的是类的元数据,加载多少类的元数据由系统的实际可用空间来控制,可以加载更多的类 JDK8 合并 HotSpot 和 JRockit 代码时,jrockit...
虚拟机中的对象
虚拟机中的对象 虚拟机类加载机制 类的生命周期 加载,验证,准备,初始化_和_卸载_这五个顺序是可以确定的,类型的加载过成必须按照这种顺序按部就班的开始, 而_解析_阶段可以在初始化阶段后再开始。(并非完成一步后再进行其他部分,通常可以交叉混合进行) 有且只有六种情况必须对类立刻进行初始化_(加载,验证等在此之前已完成); 遇到 new getstatic,putstatic或invokestatic四条字节码指令时,如果类型没有进行初始化,则会先出发其初始化阶段。生成该四种指令的典型java代码有: new 一个实例对象 读取或设置一个类型的静态字段(被final修饰或已在编译器把结果放入常量池的静态字段除外) 调用一个类型的静态方法的时候 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需 要先触发其初始化。 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先...
Volatile
Volatile Volatile的可见性和指令重排是如何实现的.内存模型的相关概念 内存模型 计算机在执行程序过程中,每条指令都是在CPU中执行的,而在执行过程中,程序的临时数据是放在主内存上的,此时就存在一个问题,CPU执行速度很快,从内存中读取和写入数据相比于CPU执行指令的速度慢很多,因此如果任何数据操作都需要和内存交互进行,会大大降低指令执行速度,因为在CPU中引入的高速缓存。 也就是说当程序在运行过程中会先将运算的数据从主存中复制一份到CPU高速缓存中,CPU直接从高速缓存中获取数据和写入数据,运算结束后在将高速缓存中的数据刷新到内存中。这种操作在单核CPU中没有问题,但是在多核CPU中就存在问题。 例如 1i = i +...
JavaWeb
JavaWeb