linux 延时一微秒

低延迟Java应用程序中的许多基准测试涉及必须在一定负载下测量系统。 这就要求保持事件进入系统的稳定吞吐量,而不是在没有任何控制的情况下以全油门将事件泵入系统。

我经常要做的任务之一是在事件之间将生产者线程暂停一小段时间。 通常,此时间量为个位数微秒。

那么,如何在此时间内暂停线程? 大多数Java开发人员会立即想到Thread.sleep() 。 但这是行不通的,因为Thread.sleep()仅下降到毫秒,并且比我们暂停所需的时间(以微秒为单位)长一个数量级。

我在StackOverflow上看到一个答案,将用户指向TimeUnit.MICROSECONDS.sleep()以便睡眠少于一毫秒。 引用JavaDoc ,这显然是不正确的:

使用此时间单位执行Thread.sleep 。 这是一种方便的方法,可以将时间参数转换为Thread.sleep方法所需的形式。

因此,您将无法获得比Thread.sleep(1)相似的1毫秒的暂停。 (您可以在下面的代码中尝试示例来证明这一点)。

这样做的原因是这种暂停方法(即使线程进入睡眠状态并唤醒它)永远不会足够快或准确到不足一毫秒。

此时我们要介绍的另一个问题是Thread.sleep(1)到底有多精确? 稍后我们将再次讨论。

当我们想暂停一微秒时,另一个选择是使用LockSupport.parkNanos(x) 。 使用以下代码停泊1微秒实际上需要约10us。 它比TimeUnit.sleep()/ Thread.sleep()更好,但并不真正适合目的。 100us之后,它确实会以50%的变化进入同一个球场。

package nanotime;import java.util.Arrays;
import java.util.concurrent.TimeUnit;/*** Created by daniel on 28/10/2015.*/
public class NanoTimer {public static void main(String[] args) throws InterruptedException {long[] samples = new long[100_000];int pauseInMillis = 1;for (int i = 0; i < samples.length; i++) {long firstTime = System.nanoTime();LockSupport.parkNanos(pauseInMicros);long timeForNano = System.nanoTime() - firstTime;samples[i] = timeForNano;}System.out.printf("Time for LockSupport.parkNanos() %.0f\n", Arrays.stream(samples).average().getAsDouble());}
}

解决我们问题的方法是使用System.nanoTime() 。 通过忙于等待对System.nanoTime的调用,我们将能够暂停一微秒。 我们将在一秒钟内看到此代码,但首先让我们了解System.nanosecond()的准确性。 至关重要的是,执行对System.nanoSecond()的调用需要多长时间。

这是一些可以完全做到这一点的代码:

package nanotime;public class NanoTimer {public static void main(String[] args) throws InterruptedException {long[] samples = new long[1_000_000];for (int i = 0; i < samples.length; i++) {long firstTime = System.nanoTime();long timeForNano = System.nanoTime() - firstTime;samples[i] = timeForNano;}System.out.printf("Time for call to nano %.0f nanseconds", Arrays.stream(samples).average().getAsDouble());}
}

在我的MBP上,从一台机器到另一台机器,数字将有所不同,大约为40纳秒。

这告诉我们,我们应该能够测量大约40纳秒的精度。 因此,应该很容易测量到1微秒(1000纳秒)。

这是忙碌的等待方法,“暂停”了微秒:

package nanotime;import java.util.Arrays;
/*** Created by daniel on 28/10/2015.*/
public class NanoTimer {public static void main(String[] args) throws InterruptedException {long[] samples = new long[100_000];int pauseInMicros = 1;for (int i = 0; i < samples.length; i++) {long firstTime = System.nanoTime();busyWaitMicros(pauseInMicros);long timeForNano = System.nanoTime() - firstTime;samples[i] = timeForNano;}System.out.printf("Time for micro busyWait %.0f\n", Arrays.stream(samples).average().getAsDouble());}public static void busyWaitMicros(long micros){long waitUntil = System.nanoTime() + (micros * 1_000);while(waitUntil > System.nanoTime()){;}}
}

该代码等待一微秒,然后乘以等待时间。 在我的机器上,我得到1,115纳秒,准确度在90%左右。

当您等待更长的时间时,精度会提高,10毫秒需要10,267纳秒,即97%的准确度,而100毫秒需要100,497纳秒,即99.5%的准确度。

那么Thread.sleep(1)到底有多精确?

这是代码:

package nanotime;import java.util.Arrays;
import java.util.concurrent.TimeUnit;/*** Created by daniel on 28/10/2015.*/
public class NanoTimer {public static void main(String[] args) throws InterruptedException {long[] samples = new long[100_000];int pauseInMillis = 1;for (int i = 0; i < samples.length; i++) {long firstTime = System.nanoTime();Thread.sleep(pauseInMicros);long timeForNano = System.nanoTime() - firstTime;samples[i] = timeForNano;}System.out.printf("Time for micro sleep %.0f\n", Arrays.stream(samples).average().getAsDouble());}
}

1毫秒睡眠的平均时间(以纳秒为单位)为1,295,509。 准确率只有〜75%。 对于几乎所有内容,它可能已经足够好了,但是如果您想要精确的毫秒级暂停,那么忙碌的等待会更好。 当然,您需要记住繁忙的等待,按照定义,繁忙的等待会使您的线程繁忙,并会花费您CPU的时间。

汇总表

暂停方式 1us 10us 100us 1000us / 1ms 10,000us / 10ms
TimeUnit.Sleep() 1284.6 1293.8 1295.7 1292.7 11865.3
LockSupport.parkNanos() 8.1 28.4 141.8 1294.3 11834.2
忙等待 1.1 10.1 100.2 1000.2 10000.2

结论

  • 如果您想暂停不到一毫秒,则需要忙于等待
  • System.nanoSecond()大约需要40ns
  • Thread.sleep(1)的准确率只有75%
  • 忙于等待超过10us或更高的时间几乎是100%准确
  • 繁忙的等待将占用CPU

翻译自: https://www.javacodegeeks.com/2015/11/lets-pause-for-a-microsecond.html

linux 延时一微秒

linux 延时一微秒_让我们暂停一微秒相关推荐

  1. java 函数 微秒_在Java中以微秒为单位解析时间

    我在解析2013-01-09 09:15:03.000000格式的Java时间字符串时遇到问题. 在我的数据中,最后三个数字始终为0(表示输入字符串仅具有毫秒精度),因此我将此格式传递给SimpleD ...

  2. linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数

    linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...

  3. 002_韦东山嵌入式Linux应用开发基础_实操碰到的问题集锦

    嵌入式Linux应用开发基础_韦东山教程思考笔记 配合<嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板> 文件目录 访问根/目录下,Filesystem Root目 ...

  4. linux延时与定时计算

    linux延时函数 高精度时间函数 高精度的设置时间函数和读取时间函数 int gettimeofday(struct timeval *tv, struct timezone *tz); int s ...

  5. linux运行隐藏文件,Linux下如何隐藏文件_网站服务器运行维护,Linux,隐藏文件

    linux系统怎样安装软件_网站服务器运行维护 linux系统安装软件的方法:1.使用apt命令进行安装,如[apt install app_name]:2.使用rpm命令进行安装,如[rpm -i ...

  6. linux 内核 网卡驱动 移植,Linux内核移植步骤_添加DM9000网卡驱动(设备树).docx

    Linux内核移植步骤_添加DM9000网卡驱动(设备树) Linux内核移植步骤2015年05月13日星期三上午 11:05往设备树中添加网卡驱动:1.选平台,指定交叉编译工具链:(1).在Make ...

  7. linux内核基本模型,Linux设备模型(1)_基本概念

    Linux设备模型(1)_基本概念 作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型 1. 前言 在"Linux内核的整体架构"中,蜗蜗有提到,由于Lin ...

  8. linux lvm 8e下继续划分分区,linux下LVM学习_逻辑卷管理

    一.LVM介绍 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制,通过LVM可以在不停机的情况下调整分区大小,提高了磁盘分区 ...

  9. Linux环境编程姜林美,Linux环境编程习题_编程题_答案.pdf

    Linux环境编程习题_编程题_答案 Linux 境编程-人民邮电出版社-姜林美 课后习题(编程题)答案 第三章 1 第五章 4 第六章 9 第七章 19 第八章 22 第九章 35 第十章 38 三 ...

最新文章

  1. php带帽接口_利用php自包含特性上传webshell
  2. yii表单ajax验证,yii2 modal弹窗之ActiveForm ajax表单异步验证
  3. [转载]spring security 的 logout 功能
  4. python脚本如何编译_如何编译用于FORTRAN的Python脚本?
  5. mysql 1054 42s22_MySQL 触发器的坑:ERROR 1054 (42S22): Unknown column 'xxx' in 'field list'
  6. Android让控件位于底部
  7. 如何编写可移植的c/c++代码
  8. XMind思维导图文件损坏,无法打开怎么办?
  9. 服务器2016系统看图软件,PhotoX:Mac上最好用的免费看图软件
  10. MATLAB中的均值与方差求法(mean,var,std函数使用)
  11. Java对中文字符串按照拼音排序的思索
  12. Android 环信 客服集成
  13. 陆白_淘宝电商代运营
  14. 新手学平面设计都会遇到哪些问题
  15. configure配置安装详解
  16. c++ bitset类用法
  17. 如何解决2D CAD DraftSight闪退或停止工作问题,干货!
  18. ADO Execute 方法 (ADO Connection)
  19. 从scratch到python轻松学下载_STEAM教育-[少儿创客] 从Scratch到Python——python turtle-电路城论坛 - 电子工程师学习交流园地...
  20. 企业如何有效管理彩打黑白打印服务

热门文章

  1. P3835-[模板]可持久化平衡树【无旋Treap】
  2. P2231-[HNOI2002]跳蚤【容斥】
  3. U94222-循环往复【tarjan,DAGdp】
  4. P3388-[模板]割点(割顶)【tarjan】
  5. P3369-[模板]普通平衡树【替罪羊树】
  6. P3957-跳房子【单调队列,dp,二分】
  7. 纪中B组模拟赛总结(2020.2.1)
  8. 常用公有云接入——华为
  9. Java自动化邮件中发送图表(四)之javafx Chart
  10. 告诉你,Spring Boot 真是个牛逼货