当前位置: 首页 > 面试题库 >

更改操作系统时间时sleep()中的Java错误:有任何解决方法?

杨昊
2023-03-14
问题内容

使我烦恼的臭虫和这张票一样。基本上,如果将操作系统时钟更改为过去的日期,则更改时休眠的所有线程都不会唤醒。

我正在开发的应用程序打算在24/24上运行,我们希望能够在不停止OS的情况下更改OS日期(例如,从夏季时间切换为冬季时间)。目前发生的事情是,当我们将日期更改为过去的日期时,应用程序的某些部分就会冻结。我在多台计算机上,Windows
XP和Linux 2.6.37以及最近的JVM(1.6.0.22)上都观察到了这一点。

我尝试了许多Java睡眠原语,但是它们都有相同的行为:

  • Thread.sleep(长)
  • Thread.sleep(long,int)
  • Object.wait(长)
  • Object.wait(long,int)
  • Thread.join(长)
  • Thread.join(long,int)
  • LockSupport.parkNanos(长)
  • java.util.Timer
  • javax.swing.Timer

现在,我不知道要解决此问题。我认为我无法采取任何措施来防止睡眠线程冻结。但是,我至少希望在检测到危险的系统时钟更改时向用户发出警告。

我想出了一个监视线程来检测这种变化:

    Thread t = new Thread(new Runnable() {
        @Override
        html" target="_blank">public void run() {
            long ms1 = System.currentTimeMillis();
            long ms2;
            while(true) {
                ms2 = ms1;
                ms1 = System.currentTimeMillis();
                if (ms1 < ms2) {
                    warnUserOfPotentialFreeze();
                }
                Thread.yield();
            }                    
        }
    });
    t.setName("clock monitor");
    t.setPriority(Thread.MIN_PRIORITY);
    t.setDaemon(true);
    t.start();

问题在于,这会使应用程序在空闲时从2%的CPU使用率增长到15%。

您是否有解决原始问题的想法,还是可以想到另一种监视线程冻结外观的方法?

编辑

Ingo建议不要触摸系统时钟。我同意通常不需要。问题在于我们无法控制客户使用计算机的行为(我们计划出售数百份)。

更糟糕:我们的一台机器没有任何人工干预就出现此问题。我猜想操作系统(Windows
XP)会定期将其时钟与RTC时钟同步,这会使操作系统时钟自然地回到时间上。

结语

我发现问题中的某些陈述是错误的。实际上,我的最初问题涉及两个单独的原因。现在,我可以肯定地说两件事:

  1. 在我的机器只(ArchLinux的内核2.6.37与OpenJDK的64位1.6.0_22) ,Thread.sleep,,Object.wait 有同样的问题:他们醒来,只有当系统时钟到达觉醒的“目标”的时间。但是,在我的shell中没有一个简单的问题。Thread.join``LockSupport.parkNanos``sleep

  2. 在所有的机器我测试(包括矿山),java.util.Timerjava.swing.Timer有同样的问题(他们被封锁,直到达到“目标”时间)。

因此,我所做的是,我用Timer一个更简单的实现替换了所有Java 。这解决了除我之外的所有机器的问题(我只是希望我的机器是一个例外,而不是一条规则)。


问题答案:

根据错误通知单,您的线程不会冻结,一旦时钟赶上修改之前的时间,它们将恢复运行(因此,如果将其移回一小时,则您的线程将在1小时内恢复运行)。

当然,这仍然不是很有用。根本原因似乎是Thread.sleep()解决一个系统调用,该调用使线程进入睡眠状态,直到将来某个特定的时间戳记为止,而不是持续指定的持续时间。要解决此问题,您需要实现自己Thread.sleep()使用的版本,System.nanoTime()而不是使用System.currentTimeMillis()API或任何其他依赖时间的API。Thread.sleep()但是,我无法在不使用内置功能的情况下做到这一点。

编辑:

或者,如果您用另一种语言(例如C或您喜欢的其他语言)创建某个外部应用程序,该应用程序除了等待指定的时间后什么都不做,然后退出,该怎么办?然后,您可以生成此外部进程的新实例,然后在其上调用waitFor(),而不是在Java中调用Thread.sleep()。这将使Java线程出于所有实际目的“休眠”,并且只要您的外部应用程序能够以正确的时间休眠,它就会在正确的时间恢复运行而不会冻结,也不会影响CPU。

解决这个问题似乎还有很长的路要走,但这是我能想到的唯一可行的解​​决方法。同样,由于产生外部进程是一个相对昂贵的操作,因此,如果您睡眠相对较长的时间(例如几百毫秒或更长),则效果最好。在较短的时间内,它可能只会继续影响CPU。



 类似资料:
  • 本文向大家介绍python修改操作系统时间的方法,包括了python修改操作系统时间的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python修改操作系统时间的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的Python程序设计有所帮助。

  • 本文向大家介绍Python中用sleep()方法操作时间的教程,包括了Python中用sleep()方法操作时间的教程的使用技巧和注意事项,需要的朋友参考一下  mktime()方法是localtime()反函数。它的参数是struct_time或全9元组,它返回一个浮点数,为了兼容时time()。 如果输入值不能表示为有效的时间,那么OverflowError或ValueError错误将被引发。

  • 不论是在我自己机器上还是其他主机上,只要部署了dokuwiki,其系统时间(也就是修改或者提交的记录时间)都会比我的本机时间晚8个小时。比如,我的本机时间是2011\9\20 22:00:00,那么记录时间就会是2011\9\20 14:00,请问如果要更改为本机时间,怎么修改? 1楼的。。。是修改linux系统的cmos时间吧,牛头不对马嘴。。。。。。 我的dokuwiki是部署在windows

  • 本文向大家介绍C++设置系统时间及系统时间网络更新的方法,包括了C++设置系统时间及系统时间网络更新的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C++设置系统时间及系统时间网络更新的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的C++程序设计有所帮助。

  • 在现实生活中,操作系统是如何计算进程的突发时间的。假设计算机有5个进程要执行,并且使用最短作业优先算法。那么操作系统如何提前知道每个进程的突发时间??

  • 我在MacBook Pro(macOS Catalina)上使用Jupyter,当我使用pandas读取CSV文件时,在执行read命令后,我得到一个操作系统错误。我如何解决这个问题? 以下是错误的显示方式: 这就是错误的显示方式错误的图片2 第三行代码后显示OS错误。