JAVA下的多线程程序造成系统时钟变快

最近的一个项目,采用JSP+Servlet开发的Web应用,功能不复杂,涉及到一些多线程处理及网络编程。测试期间发现在会造成系统时钟变快,基本运行不到一小时就快了10来分钟,开出时钟程序能明显感觉秒钟跳动比较快。检查过代码没有用到任何有关时间设置的调用,JVM、TOMCAT也换过多个版本,依然没能解决问题。由于我们的项目程序不运行时系统时钟一切正常,启动后立刻变快,初步硬件或是其他程序造成的问题。另外,最奇怪的是并不是所有机器上运行都有这种问题,公司里的3台2003Server上,2台有此现象,另一台始终正常,开发用的一些xp/vista的机器也不都存在这个问题。

着实郁闷了很长一段时间,始终找不到问题的关键,更没法找到解决办法。前两天偶然查到一篇SUN网站bug库中早些年的一篇文章:(ID:4500388)Calling Thread.sleep with small argument affects system clock on windows ,其中说明了当多线程处理时,调用Thread.sleep()方法时,若sleep的参数小于10ms就可能会造成windows系统时钟变快。不过该bug标记为jvm 1.3中才存在,并且已经在后续版本fixed,而我们开发都是用的1.6版本。于是搜索了下项目代码,确实有用到Thread.sleep()方法的地方,而且某些部分由于需求关系,程序中的参数不定的,会依据一定算法计算出来,这样就有可能小于10ms,尽管理论上我们代码中可能最小只设定到50ms左右。

接下来继续搜了下其他的bug report,包括ID为5005837 、6435126的文章,发现上述问题并未根本解决。根据文章中提到的ForceTimeHighResolution关键字google一下,发现这个参数是JVM 中的一个;另外搜到老外的帖子里有一篇关于applet游戏程序时钟走快后,其厂商给出的解决办法,就是需要开启ForceTimeHighResolution参数!

这下好了,这应该就是解决问题的关键所在。重新将项目服务器时间校准,然后在TOMCAT的catalina.bat中将JAVA_OPTS参数中增加一项 -XX:+ForceTimeHighResolution (注意 - 和 + 都是有的),启动TOMCAT运行。查看时钟,感觉没有变快,运行1小时后,未发现变快现象,看来这个参数确实很有效。剩下工作就是把所有安装项目程序的服务器都修改了参数设置,进行长时间运行测试,直至目前为止,均未在出现时钟变快的现象。

经过这件事后,确实没想到JVM还有这样的BUG。以前C#的代码写的多,接触JAVA时间不太长,这次算是见识到了JAVA中千奇百怪的问题了。不过至于程序中开启了ForceTimeHighResolution这个参数会不会带来别方面问题,还无从得知,只有待时间来检验了。如果这方面有了解的朋友欢迎与我交流。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
下面是一个简单的电子时钟案例,使用Java多线程实现: ```java import java.util.Calendar; public class ElectronicClock implements Runnable { private Thread thread; private boolean stop = false; public ElectronicClock() { thread = new Thread(this); thread.start(); } public void run() { while (!stop) { // 获取当前时间 Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); // 输出时间 System.out.printf("%02d:%02d:%02d\n", hour, minute, second); // 等待1秒钟 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void stop() { stop = true; } public static void main(String[] args) { ElectronicClock clock = new ElectronicClock(); // 运行10秒钟后停止时钟 try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } clock.stop(); } } ``` 在这个例子中,我们创建了一个`ElectronicClock`类,实现了`Runnable`接口,表示这个类是一个可以运行的线程。在构造函数中,我们创建了一个新的线程并启动它。`run()`方法中,我们使用`Calendar`类获取当前的小时、分钟和秒,并将它们输出到控制台上。然后我们调用`Thread.sleep(1000)`使线程休眠1秒钟,然后再次获取当前时间,输出时间,以此类推。`stop()`方法用于停止时钟。 在`main()`方法中,我们创建了一个`ElectronicClock`实例并启动它。然后我们让程序休眠10秒钟,最后调用`stop()`方法停止时钟
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值