Java虚拟机
程序计数器 Program Counter Register:
记录的是正在执行的虚拟机字节码指令的地址,
此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError的区
域
虚拟机:VM Stack
描述的是 JAVA 方法执行的内存模型,每个方法在执行的时候都会创建一个栈帧,
用于存储局部变量表,操作数栈,动态链接,方法接口等信息
局部变量表存储了编译期可知的各种基本数据类型、对象引用
线程请求的栈深度不够会报 StackOverflowError 异常
栈动态扩展的容量不够会报 OutOfMemoryError 异常
虚拟机栈是线程隔离的,即每个线程都有自己独立的虚拟机栈
本地方法:Native Stack
本地方法栈类似于虚拟机栈,只不过本地方法栈使用的是本地方法
堆:Heap
几乎所有的对象实例都在堆上分配内存
所有的对象实例以及数组都要在堆上分配。堆是垃圾收集器管理的主要区域,也被称为“GC
堆”;也是我们优化最多考虑的地方。
堆可以细分为:
新生代
- Eden 空间
- From Survivor 空间
- To Survivor 空间
老年代
永久代/元空间
—Java8 以前永久代,受 jvm 管理,java8 以后元空间,直接使用物理内存。因此,
默认情况下,元空间的大小仅受本地内存限制
异步执行耗时操作
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
//1、sku 基本信息获取 pms_sku_info
SkuInfoEntity info = getById(skuId);
skuItemVo.setInfo(info);
return info;
}, executor);
CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//3、获取 spu 的销售属性组合。
List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
}, executor);
CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync(res -> {
//4、获取 spu 的介绍 pms_spu_info_desc
SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesp(spuInfoDescEntity);
}, executor);
CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync(res -> {
//5、获取 spu 的规格参数信息。
List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroupVos);
}, executor);
//2、sku 的图片信息 pms_sku_images
CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
List<SkuImagesEntity> images = imagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(images);
}, executor);
//等待所有任务都完成
CompletableFuture.allOf(saleAttrFuture, descFuture, baseAttrFuture, imageFuture).get();
return skuItemVo;
}
这段代码是一个用于获取商品详情的方法。它通过异步编程的方式,从数据库中获取商品相关的信息,并将这些信息封装成一个SkuItemVo对象返回。
具体来说,它的实现逻辑如下:
- 首先创建一个SkuItemVo对象。
- 使用CompletableFuture.supplyAsync()方法创建一个异步任务,用于获取sku的基本信息。
在任务中,从数据库中获取skuId对应的sku基本信息,并将其设置到SkuItemVo对象中。 - 使用thenAcceptAsync()方法创建一个异步任务,用于获取sku的销售属性组合。
在任务中,
根据sku的spuId从数据库中获取相应的销售属性组合信息,并将其设置到SkuItemVo对象中。 - 使用thenAcceptAsync()方法创建一个异步任务,用于获取sku的介绍。
在任务中,根据sku的spuId从数据库中获取相应的介绍信息,并将其设置到SkuItemVo对象中。 - 使用thenAcceptAsync()方法创建一个异步任务,用于获取sku的规格参数信息。
在任务中,根据sku的spuId和catalogId从数据库中获取相应的规格参数信息,并将其设置到SkuItemVo对象中。 - 使用CompletableFuture.runAsync()方法创建一个异步任务,用于获取sku的图片信息。
在任务中,从数据库中获取skuId对应的图片信息,并将其设置到SkuItemVo对象中。 - 使用CompletableFuture.allOf()方法等待所有的异步任务执行完成。
- 返回构建好的SkuItemVo对象。
通过使用异步任务,可以并行地从数据库中获取不同类型的商品信息,
提高了代码的执行效率。这种方式适合处理一些耗时的操作,
可以充分利用系统资源,提升系统的响应速度。
自定义注解校验
这段代码是一个自定义校验注解 @ListValue
的定义。它用于声明可以取哪些值。
/**
* 自定义校验注解 声明可以取那些值
*/
@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.zsy.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] values() default {};
}
注解的属性和含义如下:
message()
: 校验失败时的提示信息,默认为 “{com.zsy.common.valid.ListValue.message}”。groups()
: 分组信息,默认为空。payload()
: 载荷信息,默认为空。values()
: 允许取的值数组。
该注解应用了以下元注解:
@Documented
: 表示该注解会被包含在 Java 文档中。@Constraint
: 表示该注解是一个验证约束注解,指定了验证器类ListValueConstraintValidator.class
。@Target
: 指定了注解可以应用的目标类型,包括方法、字段、注解类型、构造函数、参数和类型使用。@Retention
: 指定了注解的保留策略,即注解应该在运行时保留。
类 ListValueConstraintValidator。
该类用于验证被 @ListValue 注解标注的元素是否在指定的值数组中。
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private final Set<Integer> set = new HashSet<>();
/**
* 初始化方法
* 参数:自定义注解的详细信息
*/
@Override
public void initialize(ListValue constraintAnnotation) {
int[] values = constraintAnnotation.values();
for (int val : values) {
set.add(val);
}
}
/**
* 判断是否校验成功
*
* @param value 需要校验的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
该类具有以下方法:
initialize(): 初始化方法,用于接收 @ListValue 注解的详细信息,并将值数组转换为一个 HashSet。
isValid(): 判断是否校验成功的方法。它接收需要校验的值 value 和 ConstraintValidatorContext 对象,并通过 set (一个包含允许值的 HashSet)来判断 value 是否在允许的值数组中。
需要注意的是,该类使用了 Java 的 HashSet 来存储允许的值