system.currenttimemillis,systemcurrenttimemillis多少位

http://www.itjxue.com  2023-01-09 03:14  来源:未知  点击次数: 

java中的system.currenttimemillis()是什么东西?

System.currentTimeMillis() 获得的是自1970-1-01 00:00:00.000 到当前时刻的时间距离,类型为long

java System.currentTimeMillis()时间获取问题

System.currentTimeMillis() 返回的是 UTC 时间,你需要在此基础上加8小时就是对了。

System.currentTimeMillis() uptimeMillis() elapsedRealtime() 区别

System.currentTimeMillis() 系统时间,也就是日期时间,可以被系统设置修改,然后值就会发生跳变。

uptimeMillis 自开机后,经过的时间,不包括深度睡眠的时间

elapsedRealtime自开机后,经过的时间,包括深度睡眠的时间

所以System.currentTimeMillis()不适合计算时间间隔,eg,

now = System.currentTimeMillis()

//do something...

duration = System.currentTimeMillis() -now;

如果在do something的时候,改变了系统时间,那么 获取duration就不准了。通常在比较小的时间里,(毫秒级,秒级)一般不会有什么问题,系统时间可能不会改变。但是如果时间很长的话,那就保证不了了

uptimeMillis由于不计算睡眠时间,所以非常适合做一些特殊的时间间隔计算

elapsedRealtime 包括睡眠时间,适用于任何情况下的时间间隔计算

system.currenttimemillis()会抛出异常吗

System.currentTimeMillis()是极其常用的基础Java API,广泛地用来获取时间戳或测量代码执行时长等,在我们的印象中应该快如闪电。

但实际上在并发调用或者特别频繁调用它的情况下(比如一个业务繁忙的接口,或者吞吐量大的需要取得时间戳的流式程序),其性能表现会令人大跌眼镜。

直接看下面的Demo:

public?class?CurrentTimeMillisPerfDemo?{

????private?static?final?int?COUNT?=?100;

????public?static?void?main(String[]?args)?throws?Exception?{

????????long?beginTime?=?System.nanoTime();

????????for?(int?i?=?0;?i??COUNT;?i++)?{

????????????System.currentTimeMillis();

????????}

????????long?elapsedTime?=?System.nanoTime()?-?beginTime;

????????System.out.println("100?System.currentTimeMillis()?serial?calls:?"?+?elapsedTime?+?"?ns");

????????CountDownLatch?startLatch?=?new?CountDownLatch(1);

????????CountDownLatch?endLatch?=?new?CountDownLatch(COUNT);

????????for?(int?i?=?0;?i??COUNT;?i++)?{

????????????new?Thread(()?-?{

????????????????try?{

????????????????????startLatch.await();

????????????????????System.currentTimeMillis();

????????????????}?catch?(InterruptedException?e)?{

????????????????????e.printStackTrace();

????????????????}?finally?{

????????????????????endLatch.countDown();

????????????????}

????????????}).start();

????????}

????????beginTime?=?System.nanoTime();

????????startLatch.countDown();

????????endLatch.await();

????????elapsedTime?=?System.nanoTime()?-?beginTime;

????????System.out.println("100?System.currentTimeMillis()?parallel?calls:?"?+?elapsedTime?+?"?ns");

????}

}

执行结果如下图。

可见,并发调用System.currentTimeMillis()一百次,耗费的时间是单线程调用一百次的250倍。

如果单线程的调用频次增加(比如达到每毫秒数次的地步),也会观察到类似的情况。关注公众号Java技术栈可以获取 JVM 和多线程及更多面试题及答案。

实际上在极端情况下,System.currentTimeMillis()的耗时甚至会比创建一个简单的对象实例还要多,看官可以自行将上面线程中的语句换成newHashMap之类的试试看。

为什么会这样呢?

来到HotSpot源码的hotspot/src/os/linux/vm/os_linux.cpp文件中,有一个javaTimeMillis()方法,这就是System.currentTimeMillis()的native实现。

jlong?os::javaTimeMillis()?{

??timeval?time;

??int?status?=?gettimeofday(time,?NULL);

??assert(status?!=?-1,?"linux?error");

??return?jlong(time.tv_sec)?*?1000??+??jlong(time.tv_usec?/?1000);

}

简单来讲就是:

调用gettimeofday()需要从用户态切换到内核态;

gettimeofday()的表现受Linux系统的计时器(时钟源)影响,在HPET计时器下性能尤其差;

系统只有一个全局时钟源,高并发或频繁访问会造成严重的争用。

HPET计时器性能较差的原因是会将所有对时间戳的请求串行执行。TSC计时器性能较好,因为有专用的寄存器来保存时间戳。缺点是可能不稳定,因为它是纯硬件的计时器,频率可变(与处理器的CLK信号有关)。

关于HPET和TSC的细节可以参见:

另外,可以用以下的命令查看和修改时钟源。

~?cat?/sys/devices/system/clocksource/clocksource0/available_clocksource

tsc?hpet?acpi_pm

~?cat?/sys/devices/system/clocksource/clocksource0/current_clocksource

tsc

~?echo?'hpet'??/sys/devices/system/clocksource/clocksource0/current_clocksource

如何解决这个问题?

最常见的办法是用单个调度线程来按毫秒更新时间戳,相当于维护一个全局缓存。其他线程取时间戳时相当于从内存取,不会再造成时钟资源的争用,代价就是牺牲了一些精确度。

具体代码如下:

public?class?CurrentTimeMillisClock?{

????private?volatile?long?now;

????private?CurrentTimeMillisClock()?{

????????this.now?=?System.currentTimeMillis();

????????scheduleTick();

????}

????private?void?scheduleTick()?{

????????new?ScheduledThreadPoolExecutor(1,?runnable?-?{

????????????Thread?thread?=?new?Thread(runnable,?"current-time-millis");

????????????thread.setDaemon(true);

????????????return?thread;

????????}).scheduleAtFixedRate(()?-?{

????????????now?=?System.currentTimeMillis();

????????},?1,?1,?TimeUnit.MILLISECONDS);

????}

????public?long?now()?{

????????return?now;

????}

????

????public?static?CurrentTimeMillisClock?getInstance()?{

????????return?SingletonHolder.INSTANCE;

????}

????private?static?class?SingletonHolder?{

????????private?static?final?CurrentTimeMillisClock?INSTANCE?=?new?CurrentTimeMillisClock();

????}

}

使用的时候,直接CurrentTimeMillisClock.getInstance().now()就可以了。

不过,在System.currentTimeMillis()的效率没有影响程序整体的效率时,就不必忙着做优化,这只是为极端情况准备的。

System.currentTimeMillis与时区设置是否有关系

存在关系,这个方法是根据你当前系统的时间来的,如果你的电脑时间人为改变,它结果也会变化。

如何转换的System.currentTimeMillis;到秒

System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。

currentTimeMillis方法

public static long currentTimeMillis()

该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。

可以直接把这个方法强制转换成date类型。

代码如下:

long currentTime = System.currentTimeMillis();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy年-MM月dd日-HH时mm分ss秒");

Date date = new Date(currentTime);

System.out.println(formatter.format(date));

运行结果如下:

当前时间:2011年-08月10日-14时11分46秒

另:

可获得当前的系统和用户属性:

String osName = System.getProperty(“os.name”);

String user = System.getProperty(“user.name”);

System.out.println(“当前操作系统是:” + osName);

System.out.println(“当前用户是:” + user);

System.getProperty 这个方法可以得到很多系统的属性。

(责任编辑:IT教学网)

更多

相关网络媒体文章

推荐网络媒体文章