Java系统时钟几个值得思考的问题

System.currentTimeMillis()是依赖于系统时钟的,也就是说,如果你把自己的系统时钟更改了,这个函数的返回会立即生效,变成更改后的值;

System.nanoTime()主要用于记录一个时间段的长度,或者说一个超时,在这个过程中,你更改系统时钟也不会影响。

两个方法的精度一个是毫秒,一个是纳秒,但都是不靠普的(有些系统的时间粒度是10ms),nanoTime()的调用也会消耗几微妙,所以不靠普;

但粒度不是我讨论的重点。

 

我们程序中的timer是很常用的功能,归根到底到下面的API:

 

LockSupport. public static void parkNanos(long nanos) 

 和

 

 

Thread.sleep(long millis)

 

 

不幸的是,但它们都是基于系统时钟的。

下面是我的测试,这个测试的过程是:启动后等待10秒钟,然后打印等待的时间:

	public static void main(String[] args) throws InterruptedException {
		long s = System.nanoTime();
		int _10sec = 10 * 1000;
		LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(_10sec));
		long e = System.nanoTime();
		long used = e - s;
		System.out.println("Used:" + TimeUnit.NANOSECONDS.toMillis(used));
	}

 在运行上面程序之后,在系统命令行执行下面命令重置时间:

[atlas@atlas-pc ~]$ date && sudo date -s 16:10:40
2013年 04月 10日 星期三 16:10:57 CST
2013年 04月 10日 星期三 16:10:40 CST

 java程序输出:Used:27889

我把时钟向前拨了17s,一个park10s的程序27秒后才结束;

同样的,测试Thread:

	public static void main(String[] args) throws InterruptedException {
		long s = System.nanoTime();
		int _10sec = 10 * 1000;
		Thread.sleep(_10sec);
		long e = System.nanoTime();
		long used = e - s;
		System.out.println("Used:" + TimeUnit.NANOSECONDS.toMillis(used));
	}

 运行后,重置时钟:

[atlas@atlas-pc ~]$ date && sudo date -s 16:33:40
2013年 04月 10日 星期三 16:34:03 CST
2013年 04月 10日 星期三 16:33:40 CST

 

java程序输出:Used:33569

 

这篇文章介绍了系统时钟和Java里面的几个API。

 

结论:

当我们重置服务器的时间(有些是通过网络同步的),

1,那些依赖系统时钟的程序(timer,scheduler,etc)会出现问题,

2,依赖时间判断的心跳会出问题,

 

目前还没有解放方法。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值