并发编程与JVM
2021-02-05 15:53:17 0 举报
AI智能生成
并发编程和JVM
作者其他创作
大纲/内容
并发编程与JVM
并发编程
多线程与同步、锁
多线程
线程的状态
NEW
RUNNABLE
BLOCKED
WAITING
TIME_WAITING
TERMINATED
线程的集中实现方式
Thread
Runnable
Callable
线程中断(唤醒阻塞线程)
阻塞
轻量级阻塞(wait、time_waiting)
重量级阻塞(blocked)
thread.interrupt()
中断的方法
Thread.interrupted()
返回中断标记,同时调用此方法会清除中断标记
thread.isInterrupted()
返回中断标记,不会清除中断标记
线程优雅停止
使用逻辑flag进行中断让线程正常结束,常用
stop()
destory()
同步
synchronized
生产者消费者模式
并发编程问题
死锁
活锁
资源不足
JMM与happen-before
重排序与内存可见性的关系
重排序类型
编译器重排序
CPU指令重排序
CPU内存重排序
内存屏障
可以禁止编译器重排序和CPU指令重排序
类型
编译器的内存屏障
CPU的内存屏障
LoadLoad:禁止读和读的重排序
StoreStore:禁止写和写的重排序
LoadStore:禁止读和写的重排序
StoreLoad:禁止写和读的重排序
数据依赖性
假如对一个共享变量同时有写和读操作时,这两个操作就有数据依赖性。
有数据依赖性的操作,不能被重排序
但是数据依赖性不被重排序只能保证单个线程中,不能保证多个线程
as-if-serial语义
概念:重排序之后不影响最终结果,就像是串行化一样
单线程下
多线程下
happen-before语义
重排序经典问题
DCL问题(双重检索)
JUC
并发容器
BlockingQueue
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
DelayBlockingQueue
SynchronousQueue
线程池
原理
线程池使用
Executors
CompletableFuture
异步编程工具
使用方法
runAsync
supplyAsync
后置方法
thenRun
执行完第一个任务,直接执行第二个任务,两个任务之间没有什么关联
thenAccpt
接收上个任务的返回值,继续处理,不返回结果
thenApply
接收上个任务的返回值,继续处理,返回结果给Future
thenCompose
直接返回嵌套的CompletableFuture的结果
thenCombine
可以再做第二个任务,同时再将第一个任务和第二个任务的返回值同时做一些操作
ForkJoinPool
多线程设计模式
Single_Threaded_Execution
Immutable
Guarded_Suspension
Balking
Producer-Consumer
Read-Write Lock
Thread-Per-Message
Worker Thread
Future
JVM
java虚拟机的内存管理
概要
JVM整体架构
线程共享
方法区
是一种规范,永久代和元空间只是一种实现方式。
1.7
存放在永久代中
1.8
存放在本地内存的元数据空间
结构
类信息
类型信息
类型:类、接口、枚举、注解
类型的完整有效名称(全名=包名.类名)
这个类型直接父类的完整有效名
这个类型的修饰符
这个类型直接接口的一个有序列表
域信息
方法信息
运行时常量池
Heap(堆)
年轻代
主要是存放新创建的对象,内存大小相对会比较小,垃圾回收比较频繁
1个Eden Space
2个Suvivor Space
年轻代中的对象如果到达阈值15,就会放入老年代
老年代
主要存放JVM认为生命周期比较长的对象(经过多次Young Gen的垃圾回收后仍然存在的),内存大小相对比较大,垃圾回收也不是很频繁
永久代
没有了永久代是因为1.8的方法区的内存并不分配在堆空间中,而是存储在本地内存元空间的Metaspace中
对象分配过程
堆GC
线程私有
虚拟机栈
栈帧
局部变量区
操作数栈
动态连接
方法的返回地址
本地方法栈
程序计数器(PC寄存器)
jdk7和jdk8的JVM内存模型的区别
区别在于方法区的不同
JVM8的方法区,分为了元数据和直接内存
内存溢出
堆溢出
虚拟机栈和本地方法栈溢出
方法区和运行时常量池溢出
直接内存溢出
JVM加载机制详解
类加载子系统
类加载器
就是一个类似快递员的功能,将字节码文件通过二进制流的方式加载到方法区。
类加载的执行过程
加载
预加载
运行时加载
链接
验证
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
准备阶段是正式未类变量分配内存并设置其初始值的阶段,这些变量所使用的内存都将在方法区中分配
解析
虚拟机将常量池内的符号引用替换为直接引用的过程。
初始化
执行类构造器clinit()方法的过程
四点注意
执行clinit()方法加载类变量(静态变量),由上到下执行,可以定义变量在静态代码块引用的下面,因为定义类变量会在准备阶段做
初始化子类的类变量之前,会先初始化父类的类变量。
接口与类不同,接口在初始化的时候无需先初始化父类的类变量,而是用到了再初始化
java虚拟机会保证clinit()方法在多线程环境中保持同步,所以在一个线程占用执行clinit()方法的时候,其他线程会被阻塞,直到活动线程执行完毕
类加载器分类
引导类加载器
启动类加载器BootStrapClassLoader
由C/C++编写的,用于JVM
自定义类加载器
由Java编写的
扩展类加载器ExtentionClassLoader
系统类加载器System Classloader
用户类加载器User Defined Classloader
双亲委派模型
垃圾回收机制和回收算法
垃圾回收机制
判断对象是否已死
引用计数器算法
可达性分析算法
主要判断方法finalize()方法
再谈引用
强引用
软引用
弱引用
虚引用
垃圾收集算法
标记清除算法
标记复制算法
标记整理算法
垃圾收集器
分类
新生代收集器
Serial GC
ParNew GC
Parallel Scavenge
老年代收集器
Seial OldGC
Parallel OldGC
CMS OldGC
初始标记
并发标记
重新标记
并发清除
G1收集器
常用命令和可视化条有工具
常用命令
jps
jinfo
jstat
jstack
jmap
jhat
JVM常用工具
0 条评论
回复 删除
下一页