System.currentTimeMillis()高并发性能优化
摘要:System.currentTimeMillis()性能问题的研究、测试与优化。
性能优化使用的测试环境:
jdk版本jdk8
操作系统:
- macOS
- 版本:13.2.1
- 芯片: Apple M1
- CPU核数:8核
System.currentTimeMillis()是Java极其常用的 API,广泛地用来获取时间戳或统计代码执行耗时等,在我们的印象中应该快如闪电。但实际上在高并发、低延时的情况下,其性能表现令人大跌眼镜,调用开销明显变高。
public static void main(String[] args) throws Exception {
singleThreadTest();
multiThreadTest();
}
public static void singleThreadTest() {
//测试一百次循环,每次循环调用System.currentTimeMillis()1千万次数
for (int t = 0; t < 100; t++) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//获取一千万次时间
for (int i = 0; i < 10000000; i++) {
System.currentTimeMillis();
}
stopWatch.stop();
System.out.println(stopWatch.getTotalTimeMillis());
}
}
public static void multiThreadTest() throws Exception {
//100个线程各执行一次
CountDownLatch wait = new CountDownLatch(1);
int loopNum = 100;
CountDownLatch threadLatch = new CountDownLatch(loopNum);
for (int i = 0; i < loopNum; i++) {
new Thread(() -> {
try {
StopWatch watch = new StopWatch();
//先阻塞住所有线程
wait.await();
watch.start();
for (int j = 0; j < 10000; j++) {
System.currentTimeMillis();
}
watch.stop();
System.out.println(watch.getTotalTimeNanos());
} catch (InterruptedException e) {
} finally {
threadLatch.countDown();
}
}).start();
}
wait.countDown();
threadLatch.await();
}
执行后,控制台打印的部分执行结果如下:
由此可见,单线程执行System.currentTimeMillis()比多线程并发执行快了太多倍。至于为什么这么慢,感兴趣的童鞋可以去问问度娘,这里给出一个基于定时任务按照毫秒更新缓存时间戳的方案,也就是在内存中维护一个全局缓存,其它线程取时间戳时从内存读取,代价就是牺牲了一些精确度。具体代码如下:
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* @Author Wiener
* @Date 2023-08-12
* @Description: 缓存系统时间
*/
public class SystemClock {
private final int period;
private final AtomicLong now;
private static final String THREAD_NAME ="wienerClock";
private static class InstanceHolder {
private static final SystemClock INSTANCE = new SystemClock(1);
}
private SystemClock(int period) {
this.period = period;
this.now = new AtomicLong(System.currentTimeMillis());
scheduleClockUpdating();
}
private static SystemClock instance() {
return InstanceHolder.INSTANCE;
}
/**
* 供消费者调用,以替换原来的System.currentTimeMillis()
*/
public static long now() {
return instance().now.get();
}
private void scheduleClockUpdating() {
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1, r -> {
Thread thread = new Thread(r, THREAD_NAME);
thread.setDaemon(true);
return thread;
});
// 每毫秒获取一次系统时间,并赋值给 AtomicLong now
scheduler.scheduleAtFixedRate(() -> now.set(System.currentTimeMillis()), period, period, TimeUnit.MILLISECONDS);
}
}
在并发量大的情况下,使用SystemClock.now()
输出当前时间,有一定精度损失,但是提高了系统时间获取效率。
温馨提示,在System.currentTimeMillis()的效率没有影响程序整体吞吐量时,没有必要做这种优化,这只是为高并发情况准备的。
System.currentTimeMillis()高并发性能优化的更多相关文章
- 用Netty开发中间件:高并发性能优化
用Netty开发中间件:高并发性能优化 最近在写一个后台中间件的原型,主要是做消息的分发和透传.因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本.Net ...
- 用Netty开发中间件:高并发性能优化(转)
用Netty开发中间件:高并发性能优化 最近在写一个后台中间件的原型,主要是做消息的分发和透传.因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本.Net ...
- GNU Linux高并发性能优化方案
/*********************************************************** * Author : Samson * Date : 07/14/2015 * ...
- SpringCloud高并发性能优化
1. SpringCloud高并发性能优化 1.1. 前言 当系统的用户量上来,每秒QPS上千后,可能就会导致系统的各种卡顿,超时等情况,这时优化操作不可避免 1.2. 优化步骤 第一步:优化大SQL ...
- 高并发&性能优化(二)------系统监控工具使用
上一篇主要从总体介绍了高并发&性能优化的相关思路和方法,本篇主要介绍系统监控工具. [CPU查看工具] ------top命令(性能) 进入top命令后,按1即可看到每核CPU的运行指标与详细 ...
- Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战
视频课程内容包含: 高级 Java 架构师包含:Spring boot.Spring cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.Zer ...
- 高并发&性能优化(一)------总体介绍
[开篇词] 本文主要通过一些经典的高并发场景,以及一些基本的运维工具来讲述一些关于高并发以及性能优化相关的内容,主要包括性能瓶颈的定位,性能调优的思路和技巧等. [性能的衡量指标] ?什么是性能 性能 ...
- Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战
Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...
- 百万并发中间件系统的内核设计看Java并发性能优化
“ 这篇文章,给大家聊聊一个百万级并发的中间件系统的内核代码里的锁性能优化. 很多同学都对Java并发编程很感兴趣,学习了很多相关的技术和知识.比如volatile.Atomic.synchroniz ...
- Java架构师/高并发/高可用/高扩展/性能优化/框架源码分析实战
https://ke.qq.com/course/401944?taid=3389721334391320
随机推荐
- php的token管理类(AI生成)
当然,以下是一个简单的 PHP 类,用于生成和管理令牌(token).这个类可以生成一个随机的令牌.验证令牌是否有效,并允许设置一个令牌的过期时间. <?php class Token { pr ...
- 用DeepSeek+可灵AI+剪映制作哪吒2走T台秀AI视频 (保姆级教程)
内容首发周老师的付费社群,挑其中部分内容免费同步给公号读者 今天给大家分享如何利用DeepSeek这类AI工具,制作哪吒2走T台秀视频,保姆级的制作方法,简单易懂,小白也能轻松上手. 关键操作,分为四 ...
- Git工作流介绍
前言 工作流其实不是一个初级主题,背后的本质问题其实是有效的项目流程管理和高效的开发协同约定,不仅是Git或SVN等SCM工具的使用. 集中式工作流 如果你的开发团队成员已经很熟悉Subversion ...
- 搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装
一.安装说明 安装好了PaddleOCR后,还需要安装PPOCRLabel这个标注工具,想要自己训练模型的话,有个标注工具会起很大作用. 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工 ...
- 虚拟机使用ESXi主机物理硬盘的办法
虚拟机使用ESXi主机物理硬盘的办法 weixin_33928137 于 2018-06-19 15:22:06 发布 868 收藏 1文章标签: 运维版权 VMware Workstation的虚拟 ...
- WIN2012域用户添加和批量添加工具
WIN2012域用户添加和批量添加,不需要进行复杂的进电脑管理去添加 直接在软件上就可单个用户添加,可批量添加,并把指定的用户加入组 可以自定义组织单位,使用起来比较简单方便. 链接:https:// ...
- GPU CPU运算时间测试
GPU CPU运算时间测试 本文主要探讨GPU,CPU在做一些复杂运算的时间测试 实验任务 1.向量加法 两个相同维度的向量a,b做加法,分别测试GPU并行时间(包含数据拷贝时间),CPU串行时间. ...
- 用 PHP 封装的发送邮件类
点击查看代码 <?php class MailSender { // 发件人邮箱地址 private $fromEmail; // 发件人名称 private $fromName; // 收件人 ...
- Visual Studio 2017 导出 ASP.NET Core 项目模版项目文件为空
问题重现 VS 2017 针对 ASP.NET Core 导出模版功能有问题 解决办法 visual-studio-2017-templates-and-the-missing-content 目前官 ...
- 主存的扩展及其CPU的连接——位扩展
其初始状态 进行读操作: 输入对应地址,将MREQ端设置为低电平,此时片选端有效,r/w端为高电平,所以写使能端无效,然后通过数据线和数据总线,CPU读取数据. 进行写操作: 输入对应地址,将R/W设 ...