程序设计的5个底层逻辑,决定你能走多快
JVM 中针对 volatile 以及 锁 的实现有 happen-before 规则, JVM 底层通过插入内存屏障来限制编译器的重排序,以 volatile 为例,内存屏障将不允许 在 volatile 字段写操作之前的语句被重排序到写操作后面 , 也不允许读取 volatile 字段之后的语句被重排序带读取语句之前。插入内存屏障的指令,会根据指令类型不同有不同的效果,例如在 monitorexit 释放锁后会强制刷新缓存,而 volatile 对应的内存屏障会在每次写入后强制刷新到主存,并且由于 volatile 字段的特性,编译器无法将其分配到寄存器,所以每次都是从主存读取,所以 volatile 适用于读多写少得场景,最好只有个线程写多个线程读,如果频繁写入导致不停刷新缓存会影响性能。 关于应用程序中设置多少线程数合适的问题,我们一般的做法是设置 CPU 最大核心数 * 2 ,我们编码的时候可能不确定运行在什么样的硬件环境中,可以通过 Runtime.getRuntime().availableProcessors() 获取 CPU 核心。 但是具体设置多少线程数,主要和线程内运行的任务中的阻塞时间有关系,如果任务中全部是计算密集型,那么只需要设置 CPU 核心数的线程就可以达到 CPU 利用率最高,如果设置的太大,反而因为线程上下文切换影响性能,如果任务中有阻塞操作,而在阻塞的时间就可以让 CPU 去执行其他线程里的任务,我们可以通过 线程数量=内核数量 / (1 - 阻塞率)这个公式去计算最合适的线程数,阻塞率我们可以通过计算任务总的执行时间和阻塞的时间获得。 目前微服务架构下有大量的RPC调用,所以利用多线程可以大大提高执行效率,我们可以借助分布式链路监控来统计RPC调用所消耗的时间,而这部分时间就是任务中阻塞的时间,当然为了做到极致的效率最大,我们需要设置不同的值然后进行测试。 Java 中如何实现定时任务 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |