linux 延时一微秒_让我们暂停一微秒
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 延时一微秒_让我们暂停一微秒相关推荐
- java 函数 微秒_在Java中以微秒为单位解析时间
我在解析2013-01-09 09:15:03.000000格式的Java时间字符串时遇到问题. 在我的数据中,最后三个数字始终为0(表示输入字符串仅具有毫秒精度),因此我将此格式传递给SimpleD ...
- linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数
linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...
- 002_韦东山嵌入式Linux应用开发基础_实操碰到的问题集锦
嵌入式Linux应用开发基础_韦东山教程思考笔记 配合<嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板> 文件目录 访问根/目录下,Filesystem Root目 ...
- linux延时与定时计算
linux延时函数 高精度时间函数 高精度的设置时间函数和读取时间函数 int gettimeofday(struct timeval *tv, struct timezone *tz); int s ...
- linux运行隐藏文件,Linux下如何隐藏文件_网站服务器运行维护,Linux,隐藏文件
linux系统怎样安装软件_网站服务器运行维护 linux系统安装软件的方法:1.使用apt命令进行安装,如[apt install app_name]:2.使用rpm命令进行安装,如[rpm -i ...
- linux 内核 网卡驱动 移植,Linux内核移植步骤_添加DM9000网卡驱动(设备树).docx
Linux内核移植步骤_添加DM9000网卡驱动(设备树) Linux内核移植步骤2015年05月13日星期三上午 11:05往设备树中添加网卡驱动:1.选平台,指定交叉编译工具链:(1).在Make ...
- linux内核基本模型,Linux设备模型(1)_基本概念
Linux设备模型(1)_基本概念 作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型 1. 前言 在"Linux内核的整体架构"中,蜗蜗有提到,由于Lin ...
- linux lvm 8e下继续划分分区,linux下LVM学习_逻辑卷管理
一.LVM介绍 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制,通过LVM可以在不停机的情况下调整分区大小,提高了磁盘分区 ...
- Linux环境编程姜林美,Linux环境编程习题_编程题_答案.pdf
Linux环境编程习题_编程题_答案 Linux 境编程-人民邮电出版社-姜林美 课后习题(编程题)答案 第三章 1 第五章 4 第六章 9 第七章 19 第八章 22 第九章 35 第十章 38 三 ...
最新文章
- php带帽接口_利用php自包含特性上传webshell
- yii表单ajax验证,yii2 modal弹窗之ActiveForm ajax表单异步验证
- [转载]spring security 的 logout 功能
- python脚本如何编译_如何编译用于FORTRAN的Python脚本?
- mysql 1054 42s22_MySQL 触发器的坑:ERROR 1054 (42S22): Unknown column 'xxx' in 'field list'
- Android让控件位于底部
- 如何编写可移植的c/c++代码
- XMind思维导图文件损坏,无法打开怎么办?
- 服务器2016系统看图软件,PhotoX:Mac上最好用的免费看图软件
- MATLAB中的均值与方差求法(mean,var,std函数使用)
- Java对中文字符串按照拼音排序的思索
- Android 环信 客服集成
- 陆白_淘宝电商代运营
- 新手学平面设计都会遇到哪些问题
- configure配置安装详解
- c++ bitset类用法
- 如何解决2D CAD DraftSight闪退或停止工作问题,干货!
- ADO Execute 方法 (ADO Connection)
- 从scratch到python轻松学下载_STEAM教育-[少儿创客] 从Scratch到Python——python turtle-电路城论坛 - 电子工程师学习交流园地...
- 企业如何有效管理彩打黑白打印服务
热门文章
- P3835-[模板]可持久化平衡树【无旋Treap】
- P2231-[HNOI2002]跳蚤【容斥】
- U94222-循环往复【tarjan,DAGdp】
- P3388-[模板]割点(割顶)【tarjan】
- P3369-[模板]普通平衡树【替罪羊树】
- P3957-跳房子【单调队列,dp,二分】
- 纪中B组模拟赛总结(2020.2.1)
- 常用公有云接入——华为
- Java自动化邮件中发送图表(四)之javafx Chart
- 告诉你,Spring Boot 真是个牛逼货