My Effective Java
我的Effective Java开发笔记
我的Effective Java开发笔记
上篇博客是线程池的源码分析,这篇是关于延时线程池的源码分析(JDK1.8)。
ScheduledThreadPoolExecutor继承了ThreadPoolExecutor类,实现了ScheduledExecutorService接口。ScheduledThreadPoolExecutor 支持延后执行给定task,或是定期执行。任务在到时间后执行,但是没有任何的实时保证。对于计划执行时间相同的任务,会按照提交顺序,先进先出执行。
A point in program where the state of execution is known by the VM。
HotSpot的安全点定义: Safepoint 是程序执行过程中的一个点,在这个点,所有的GC根都是已知的,所有的堆对象内容都是一致的。从全局角度来看,所有的线程都必须在安全点阻塞,然后GC才能运行。(作为一种特殊情况,运行JNI代码的线程可以继续运行,因为它们只使用句柄。在安全点期间,它们必须阻塞而不是加载句柄的内容。)从局部角度来看,安全点是代码块中的一个特别点,执行线程可能会在该点阻塞GC。大多数执行点都符合安全点的条件。每个安全点都有强不变量,这些不变量在非安全点可能会被忽略。
总而言之,Safepoint 指在 Java 虚拟机中,程序执行时的一个特殊点。在 Safepoint 处,所有的线程都会被暂停下来,以便进行JVM 的一些特定的操作1。例如:
-XX:GuaranteedSafepointInterval配置的时间,都会让所有线程进入 Safepoint,一旦所有线程都进入,立刻从 Safepoint 恢复。这个定时主要是为了一些没必要立刻 Stop the world 的任务执行,推荐设置-XX:GuaranteedSafepointInterval=0关闭这个定时最近的工作需要在服务端生成报表图片,Java库生成的图片实在是惨不忍睹,酷炫的还是要看JS😂。解决方案是: 服务数据 + html模板 + headless浏览器。
JDK 从Java 9开始 在包之上引入了一个新的抽象级别,正式名称为 Java 平台模块系统 (JPMS),简称“模块”。Java 模块是一种打包机制,使您能够将 Java 应用程序或 Java API 打包为单独的 Java 模块。Java 模块被打包为模块化 JAR 文件。Java 模块可以指定它包含哪些 Java 包,这些包应该对使用此模块的其他 Java 模块可见。Java 模块还必须指定完成其工作所需的其他 Java 模块。
Spring @Transactional的配置方式有两种:
1 | <!-- 事务管理器配置,单数据源事务 --> |
@Transactional("myTransactionManager")注解.Future接口可以构建异步应用,但依然有其局限性。它很难直接表述多个Future 结果之间的依赖性。实际开发中,我们经常需要达成以下目的:
Stream 是 Java 8 新特性,可对 Stream 中元素进行函数式编程操作,例如 map-reduce。Stream 表示一个序列,其中的元素支持串行或并行的聚合方法。
1 | int sum = widgets.stream() |
Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作。原子变量的底层使用了处理器提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞。
缓存系统中是以缓存行(cache line)为单位存储的。缓存行是2的整数幂个连续字节,一般为32-256个字节。最常见的缓存行大小是64个字节。CPU每次从主存中拉取数据时,会把相邻的数据也存入同一个cache line。
一个Java的long类型变量是8字节,因此在一个缓存行中可以存8个long类型的变量。在访问一个long数组的时候,如果数组中的一个值被加载到缓存中,它会自动加载另外7个。因此你能非常快的遍历这个数组。事实上,你可以非常快速的遍历在连续内存块中分配的任意数据结构。