Java中的纳秒

2023-05-16

Java中的纳秒

    • 前言
    • JDK8获取纳秒的问题
    • JDK9之后获取纳秒的问题
    • 参考资料

前言

最近在使用InfluxDB保存系统的操作日志,如果在插入的时候不指定time字段,influxDB会默认设置time,但一般来说,数据经过多方周转如果采用默认的插入时间,对业务来说误差较高。我们的日志是发送给kafka,然后消费者订阅kafka消费数据再保存到influxDB,数据会有延迟。因此会在数据产生的时候写入time字段值,对时间的精度要求比较高,这样才能有效防止数据丢失。
Java中时间精度最高的应该是纳秒了,所以查询了下获取纳秒的一些方法。

JDK8获取纳秒的问题

JDK8中提供了丰富的时间的工具类,但是实际上JDK8中没有真正获取纳秒的方法,可查看这篇文章,https://stackoverflow.com/questions/1712205/current-time-in-microseconds-in-java,
Instant类中可以获取纳秒的方法,本质上是获取的毫秒,后6位都是0。

Instant instant = Instant.now();
int tt = instant.getNano(); 
System.out.println(tt); 
//返回的时间为576000000,后6位都是0>

查看java.time.Clock类的源码可发现,本质是获取当前的System.currentTimeMillis()生成时间类的。

    static final class SystemClock extends Clock implements Serializable {
        private static final long serialVersionUID = 6740630888130243051L;
        private final ZoneId zone;

        SystemClock(ZoneId zone) {
            this.zone = zone;
        }
        @Override
        public ZoneId getZone() {
            return zone;
        }
        @Override
        public Clock withZone(ZoneId zone) {
            if (zone.equals(this.zone)) {  // intentional NPE
                return this;
            }
            return new SystemClock(zone);
        }
        @Override
        public long millis() {
            return System.currentTimeMillis();
        }
        @Override
        public Instant instant() {
            return Instant.ofEpochMilli(millis());//本质是获取当前的毫秒时间戳生成时间类的
        }
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof SystemClock) {
                return zone.equals(((SystemClock) obj).zone);
            }
            return false;
        }
        @Override
        public int hashCode() {
            return zone.hashCode() + 1;
        }
        @Override
        public String toString() {
            return "SystemClock[" + zone + "]";
        }
    }

Jdk还有一个方法System.nanoTime()可以提供纳秒的精度测量的方法,一般可以用来计算2个方法之间的差值,不能直接转成时间戳。

long startTime = System.nanoTime();
// ... the code being measured ...
long elapsedNanos = System.nanoTime() - startTime;
//To compare elapsed time against a timeout, use

可以利用这个特性,初始化t1,获取差值从而获取纳秒。

t1=System.nanoTime(),
offset=System.currentTimeMillis()*1_000_000 - t1,
//获取当前的纳秒
currentNano=System.nanoTime() + offset

https://github.com/jenetics/jenetics/blob/master/jenetics/src/main/java/io/jenetics/util/NanoClock.java 就是利用这个方法实现的。

JDK9之后获取纳秒的问题

之前有提过这方面的缺陷,https://bugs.openjdk.java.net/browse/JDK-8068730,JDK9之后优化了获取纳秒的问题。

Instant instant = Instant.now();
int tt = instant.getNano(); 
System.out.println(tt); 
//返回的时间为72765400,已经包含了纳秒。

java.time.Clock源码里,增加了VM.getNanoTimeAdjustment方法获取纳秒。

        public Instant instant() {
            // Take a local copy of offset. offset can be updated concurrently
            // by other threads (even if we haven't made it volatile) so we will
            // work with a local copy.
            long localOffset = offset;
            long adjustment = VM.getNanoTimeAdjustment(localOffset);

            if (adjustment == -1) {
                // -1 is a sentinel value returned by VM.getNanoTimeAdjustment
                // when the offset it is given is too far off the current UTC
                // time. In principle, this should not happen unless the
                // JVM has run for more than ~136 years (not likely) or
                // someone is fiddling with the system time, or the offset is
                // by chance at 1ns in the future (very unlikely).
                // We can easily recover from all these conditions by bringing
                // back the offset in range and retry.

                // bring back the offset in range. We use -1024 to make
                // it more unlikely to hit the 1ns in the future condition.
                localOffset = System.currentTimeMillis()/1000 - 1024;

                // retry
                adjustment = VM.getNanoTimeAdjustment(localOffset);

                if (adjustment == -1) {
                    // Should not happen: we just recomputed a new offset.
                    // It should have fixed the issue.
                    throw new InternalError("Offset " + localOffset + " is not in range");
                } else {
                    // OK - recovery succeeded. Update the offset for the
                    // next call...
                    offset = localOffset;
                }
            }
            return Instant.ofEpochSecond(localOffset, adjustment);
        }

这时候如要获取纳秒的时间戳就简单了。

Instant instant = Instant.now();
int tt = instant.getNano();                // Represent a moment in UTC.
long time = instant.toEpochMilli()/1000*1000_000_000 + tt;
System.out.println(time);

参考资料

  1. https://stackoverflow.com/questions/1712205/current-time-in-microseconds-in-java
  2. https://bugs.openjdk.java.net/browse/JDK-8068730
  3. https://github.com/jenetics/jenetics/blob/master/jenetics/src/main/java/io/jenetics/util/NanoClock.java
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的纳秒 的相关文章

  • JMeter

    Apache JMeter 压力测试工具 一 什么是Apache JMeter Apache JMeter 是 Apache 组织基于 Java 开发的压力测试工具 xff0c 用于对软件做压力测试 JMeter 最初被设计用于 Web 应
  • C++11向线程函数传递参数

    template span class token operator lt span class Function span class token punctuation span class span class token punct
  • C++11之std::future对象使用说明

    std future介绍 在前面几篇文章中基本都用到thread对象 xff0c 它是C 43 43 11中提供异步创建多线程的工具 但是我们想要从线程中返回异步任务结果 xff0c 一般需要依靠全局变量 xff1b 从安全角度看 xff0
  • delete 和 delete[]真正区别

    我们通常从教科书上看到这样的说明 xff1a delete 释放new分配的单个对象指针指向的内存 delete 释放new分配的对象数组指针指向的内存 那么 xff0c 按照教科书的理解 xff0c 我们看下下面的代码 xff1a spa
  • Activity的onNewIntent

    一个应用的Activity可供多种方式调用启动 xff0c 当多个调用希望只有一个Activity的实例存在 xff0c 并且还要区分是被谁启动或是已经启动被谁拉到前台来的 xff0c 这就需要Activity的onNewIntent In
  • at 与 crontab调度命令详解

    目录 1 At调度 只执行一次 1 1准备任务 xff1a 查看at服务是否开启 1 2绝对时间定制任务 1 3相对时间定制任务 1 4查看at进程 1 5删除at任务 2 crontab调度 可重复执行 2 1简述 2 2crontab调
  • [计算机网络] --- STP (下篇) 工作原理及配置

    文章目录 前言一 stp工作原理二 stp计算过程 工作步骤1 选举根桥2 选举根端口3 选举指定端口4 确立阻塞端口 三 例题 xff1a 前言 上一篇文章我们介绍了stp的起源和一些相关术语 xff0c 接下来我们就正式开始介绍stp的
  • iOS富文本实现(一):私密阅读效果

    废话不多说 xff0c 咱们直接先看效果 xff01 看是不是咱想要的哈 目录 xff1a 一 前言 xff1a 二 核心需求说明 三 实现效果核心代码片段 四 几个注意的小细节 一 前言 xff1a 我的第一篇CSDN文章就这样发布了 x
  • 登录 注册 servlet基础

    工具类 页面与数据库的交换 span class token keyword package span org span class token punctuation span lizhenhua span class token pun
  • 解决Ubuntu开机之后不显示桌面图标,只显示桌面文件的问题

    Ubuntu开机之后不显示桌面图标 xff08 指左侧那一栏 xff09 xff0c 但桌面上的文件可以使用 xff0c 鼠标可以使用 鼠标右键 gt 打开终端 xff1b xff08 如果鼠标不能使用 xff0c 按ctl 43 alt
  • yii2中登录后跳转回登录前请求的页面

    yii2中登录后跳转回登录前请求的页面 作者 php 发布时间 2017 06 16 浏览 1030次 转发请备注原文地址 xff1a www niwoxuexi com blog php article 158 html yii2中登录后
  • Gateway

    Gateway SpringCloud微服务网关组件 一 Spring Cloud Gateway简介 1 为什么要用Gateway xff1f 在微服务架构中 xff0c 通常一个系统会被拆分为多个微服务 xff0c 微服务之间的调用可以
  • Android(安卓)时间戳和日期之间的转化

    注 xff1a 转发请注明原地址 xff1a https www niwoxuexi com blog android article 170 在Android开发过程中 xff0c 经常会遇到日期的各种格式转换 xff0c 主要使用Sim
  • 如何判断Activity是否在前台显示

    转发请备注原文地址 xff1a https www niwoxuexi com blog android00 article 223 html 我们在Android开发过程中 xff0c 经常会判断Activity是否在前台显示 xff0c
  • Android 获取cache缓存的目录路径

    转发请备注原文地址 xff1a https www niwoxuexi com blog android00 article 224 html Android开发中 xff0c 有时需要知道cache缓存的路径 我写了一个静态类 xff0c
  • objc[8715]: Class JavaLaunchHelper is implemented in both...

    在Mac上 xff0c 升级IntelliJ Idea 2017 01后 xff0c 运行的时候出现了一个红色的警告 xff1a objc 8715 Class JavaLaunchHelper is implemented in both
  • mac上使用dex2jar遇到的权限问题的解决

    本文来自 xff1a https www niwoxuexi com blog android article 235 html 摘要 在dex2jar目录下执行sudo sh d2j dex2jar sh classes dex时报错如下
  • Android Studio将module变为library

    本文来源你我学习网 xff1a 地址 https www niwoxuexi com blog android article 244 html 我们在开发的时候如在在Android Studio中的module打包成library方便模块
  • Navicat Premium实现mysql数据库备份/还原

    转发请备注原文地址 xff1a https www niwoxuexi com blog php article 161 htm Navicat Premium 是一个非常好用的数据库 xff08 支持 MySQL SQLite Oracl
  • 在vue中获取dom元素

    转发请备注原文链接地址 xff1a https www niwoxuexi com blog web article 307 html 在vue中经常会通过js操作dom对象 xff0c 可以通过给标签添加ref属性实现 xff0c 下面通

随机推荐

  • HIVE总结

    一 xff1a hive作用 Hive是基于Hadoop的一个数据仓库工具 xff0c 可以将结构化的数据文件映射为一张表 xff0c 并提供类SQL 查询功能 Hive本质 xff1a 将HQL转化成MapReduce程序 xff08 1
  • 微软2014校园招聘笔试题

  • Seata

    Seata 微服务分布式事务组件 一 什么是分布式事务 1 什么是事务 事务指的是一个操作单元 xff0c 在这个操作单元中的所有操作最终要保持一致的行为 xff0c 要么所有操作都成功 xff0c 要么所有的操作都被撤销 2 本地事务 本
  • 测试用例优先级与三轮测试的结合

    测试用例优先级与三轮测试的结合 发布时间 2009 7 10 15 01 作者 meizhu 来源 Taobao QA Team 字体 小 中 大 上一篇 下一篇 打印 我要投稿 每周一问 xff0c 答贴有奖 测试用例优先级 三轮测试 x
  • Windows 10 家庭中文版,电脑文件夹背景、Word背景全变成黑色的解决方案

    电脑桌面空白处点击鼠标右键 gt 个性化 gt 颜色 xff1b 在 选择颜色 下拉菜单中选择 浅色 选项 这样 xff0c 电脑文件夹的背景和其他界面颜色就都回归了正常的亮白色
  • AbstractApplicationContext.refresh()方法

    refresh public void refresh throws BeansException IllegalStateException synchronized this startupShutdownMonitor 准备好刷新上下
  • HBase StoreFile原理总结

    HBase StoreFile原理总结 1 StoreFile是什么 在hbase架构设计中 xff0c 本身hbase基于hdfs进行数据存储 同时为了提升效率 xff0c 数据会有一个memstore block cache来做数据缓存
  • ubuntu设置关机时自动执行任务

    背景说明 本机环境 xff1a ubuntu16 04 需求 本机关机时调用远程服务用来记录日志等操作 systemd说明 ubuntu16 04采用的是systemd作为系统管理的子系统 xff0c 关于systemd的更多说明 xff0
  • Linux下zabbix_proxy实施部署

    简介 zabbix proxy 可以代替 zabbix server 收集性能和可用性数据 然后把数据汇报给 zabbix server 并且在一定程度上分担了zabbix server 的压力 zabbix agent可以指向多个prox
  • 巧用nautilus解决ubuntu文件目录、文件的权限问题

    有没有遇到这样的烦恼 xff1a 有时想给一个目录的文件进行增删 xff0c 单是因为权限问题 xff0c 无法进行操作 虽然可以用sudo 43 命令行来解决 xff0c 但是觉得操作起来还是不太方便 如果可以跟平时一样 xff0c 在图
  • Android 屏幕旋转的处理

    1 不做任何处理的情况下 如果没有针对性地做任何处理的话 xff0c 默认情况下 xff0c 当用户手机的重力感应器打开后 xff0c 旋转屏幕方向 xff0c 会导致app的当前activity发生onDestroy gt onCreat
  • Python txt文件创建,写入,保存

    实现功能介绍 xff1a 新建文本文件 xff0c 以日期命名 xff0c 判断如果存在则后缀加1 xff0c 循环按行写入内容并保存 首先指定要写入文件的内容 xff0c 并使用 datetime 模块获取当前日期 然后 xff0c 我们
  • Centos 7 / 8 安装oracle jdk 和jenkins步骤及一些常见的问题。

    废话不多说 xff0c 先说自己总结的经验 xff0c 不推荐用解压jdk压缩包 xff08 jdk 8u321 linux x64 tar gz xff09 然后配置环境变量的方式安装java 最好用yum包安装java或者是用rpm方式
  • adobe xd_如何在Adobe XD中创建Finance App UI设计

    adobe xd 在本教程中 xff0c 您将学习如何在Adobe XD中创建财务应用程序设计 xff0c 以及 xff08 更重要的是 xff09 如何轻松对其UI的各个部分进行动画处理 您将在本Adobe XD教程中学到什么 如何在Ad
  • 今天配置问题总结2023/3.13

    关于SSL库的安装 openssl和openssl devel Ubuntu系统上 首先安装openssl sudo apt get install openssl 在安装openssl devel sudo apt get install
  • 分辨率PPI(Pixel Per Inch)与DPI(Dot Per Inch)

    分辨率PPI与DPI xff0c 关于这个问题 xff0c 现在很多人容易混淆 xff0c 现摘录几份资料 图像分辨率所使用的单位是PPI xff08 Pixel Per Inch xff09 xff0c 意思是 xff1a 在图像中每英寸
  • 【自动驾驶技术】优达学城无人驾驶工程师学习笔记(七)——计算机视觉基础

    计算机视觉基础目录 前言颜色选择 xff08 Color Selection xff09 理论基础代码实践 区域筛选 xff08 Region Masking xff09 理论基础代码实践 Canny边缘检测问题背景Canny边缘检测原理代
  • Fragment 实现底部导航栏的切换(Kotlin语言)

    整个过程 1 整体结构图与效果图2 引入Kotlin扩展插件3 创建各页面布局文件 xff08 1 xff09 底端导航栏 xff08 2 xff09 信息 xff0c 联系人 xff0c 个人信息界面 信息页面布局 xff1a 联系人界面
  • 关于onNewIntent()

    普通的Activity之间的跳转 xff0c 如 xff1a 新打开一个Activity xff0c 此时的执行顺序是0nCreat xff0d onStart xff0d onResume 此时使用Intent 传递数据没有问题 xff0
  • Java中的纳秒

    Java中的纳秒 前言JDK8获取纳秒的问题JDK9之后获取纳秒的问题参考资料 前言 最近在使用InfluxDB保存系统的操作日志 xff0c 如果在插入的时候不指定time字段 xff0c influxDB会默认设置time xff0c