V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
NeoZephyr
V2EX  ›  Java

Java 中有比较精确的微秒级别的延迟方法吗

  •  
  •   NeoZephyr · Jul 21, 2022 · 4024 views
    This topic created in 1379 days ago, the information mentioned may be changed or developed.

    我看了一下,c 里面有 struct timeval 结构体,时间可以精确到微秒,而且使用 select 会比 sleep 更好

    但是,在 java 里面,最多才到毫秒级别,而且 sleep 的方式,也容易出现误差

    不知道是否有其他方式实现,比较准确的延迟

    22 replies    2022-07-26 08:30:53 +08:00
    wombat
        1
    wombat  
       Jul 21, 2022
    就算 sleep 了那么微秒,可能 cpu 调度执行的时候,是延迟的吧。
    mawerss1
        2
    mawerss1  
       Jul 21, 2022
    不说 java ,操作系统级别也没有吧
    feather12315
        3
    feather12315  
       Jul 21, 2022 via Android   ❤️ 1
    @mawerss1 #2 OS 都有纳秒级别的延迟手段
    mxalbert1996
        4
    mxalbert1996  
       Jul 21, 2022 via Android   ❤️ 5
    如果你需要精确到微妙级的对时间的掌控,那你根本就不应该用 Java 这种带 GC 的语言。
    v2eb
        5
    v2eb  
       Jul 21, 2022 via Android
    开发什么功能🙊
    lzfnb
        6
    lzfnb  
       Jul 21, 2022
    LockSupport.parkNanos() ?
    reid567
        7
    reid567  
       Jul 21, 2022
    TimeUnit.MICROSECONDS.sleep(); 这种吗?
    NeoZephyr
        8
    NeoZephyr  
    OP
       Jul 21, 2022
    @jiajianjava 好像不行,里面还是 Thread.sleep
    NeoZephyr
        9
    NeoZephyr  
    OP
       Jul 21, 2022
    @v2eb 延时消息、事件的功能
    LeeReamond
        10
    LeeReamond  
       Jul 21, 2022 via Android
    @mxalbert1996 零度要求也分级别的,要求微秒也未必 100%场景都要微秒。常见场景比如统计一秒内能做 xxx 事之类的,统计过程中基本准确即可,不需要服务级稳定
    elfive
        11
    elfive  
       Jul 21, 2022 via iPhone
    Windows C++延时器,精度没有到 us ,不是 RTOS ,不可能有这种精度。
    用多媒体计时器做成的延时器也只能最好到 1ms 精度。
    newmlp
        12
    newmlp  
       Jul 21, 2022
    没有
    jptx
        13
    jptx  
       Jul 21, 2022
    好奇到底是什么样的场景,需要 Java 来实现而且需要延迟精确到微秒,应该有别的解决方案
    mxalbert1996
        14
    mxalbert1996  
       Jul 21, 2022 via Android
    @LeeReamond 如果只是要计时的话当然没问题,Java 里也有 System.nanoTime(),但楼主要的是延迟,也就是我所说的「对时间的控制」。
    NeoZephyr
        15
    NeoZephyr  
    OP
       Jul 21, 2022
    @jptx 我的场景只需要到秒就可以了。我只是突然看到有关时间轮的实现,发现 java 里面延迟都是毫秒级别的,好奇问下大家
    nothingistrue
        16
    nothingistrue  
       Jul 22, 2022
    我是没发现 JDK 有精确控制时钟(基于精确时钟触发操作,不是获取精确时钟刻度)的 API ,考虑到 Java 运行在 JVM 而不是 OS 上,JDK 要没这 API ,第三方框架也做不了。

    时间轮那个,原本就不是精确延迟时间,其实毫秒级别都已经过了,大量任务跑起来,误差都是上分钟级别的。选择毫秒那是因为在不用时钟的情况下 Java 能读取的时间刻度的单位最低就到毫秒。
    NeoZephyr
        17
    NeoZephyr  
    OP
       Jul 22, 2022
    @nothingistrue

    时间轮误差这么大吗?那 linux 自己的时间轮,不是也有问题吗,感觉不太可能吧。

    如果 java 延迟误差那么大的话,那一些中间件提供的延迟队列,不也有问题吗?误差到分钟级别,怎么也接受不了啊
    muyiluop
        18
    muyiluop  
       Jul 22, 2022
    时间轮肯定是有误差的,你想想同一个时刻要执行的任务越多不就需要越长时间么,你也不可能做到让所有任务都同时执行
    nothingistrue
        19
    nothingistrue  
       Jul 22, 2022   ❤️ 1
    @NeoZephyr 先拿 Thread.sleep 来说,sleep 100 毫秒,只是告诉线程调度者要休眠 100 毫秒,但线程调度者并不会严格按照 100 毫秒去休眠,而是首先照顾自身的调度机制,这样就会产生误差。在线程调度级别,这个误差很小,几乎可以忽略。到了时间轮上,误差也是这么来的,误差的大小取决于时间轮的调度配置。配的调度间隔小,误差就小,但轮询消耗高。配置的调度间隔大,误差就大,但轮询消耗小。

    时间轮的误差大不大,取决于怎么配置,linux 的是操作系统级别任务,配的误差就小。对于现实业务,误差是允许很多大的,比如说“一天后自动退款”,你给误差 1 小时甚至 12 小时都允许。这时候就可以照顾性能,给时间轮配置大的调度间隔。
    Chinsung
        20
    Chinsung  
       Jul 22, 2022
    Java 级别很难实现吧,如果发生 gc stw 了呢?微妙级别很难准确
    goalidea
        21
    goalidea  
       Jul 24, 2022
    jni
    mmdsun
        22
    mmdsun  
       Jul 26, 2022 via iPhone   ❤️ 1
    有关系统时间误差,可以参考:
    https://docs.microsoft.com/zh-cn/windows/win32/sysinfo/acquiring-high-resolution-time-stamps#low-level-hardware-clock-characteristics

    简单的 Win 上任务管理器右键,就能把程序进程设置成实时的。普通 Win 系统可以做到软实时。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2514 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 06:13 · PVG 14:13 · LAX 23:13 · JFK 02:13
    ♥ Do have faith in what you're doing.