在Java中划分长值时不一致
我知道这看起来很疯狂,我现在一直在为它挠头,我很确定我遗漏了一些东西 我正在计算从那天开始到现在发生的“分钟数”。为此,我正在做以下工作:在Java中划分长值时不一致,java,timestamp,overflow,long-integer,Java,Timestamp,Overflow,Long Integer,我知道这看起来很疯狂,我现在一直在为它挠头,我很确定我遗漏了一些东西 我正在计算从那天开始到现在发生的“分钟数”。为此,我正在做以下工作: long startTime = System.currentTimeMillis(); // Below mod function gets code to start of the day long lastStart = startTime - (startTime % (TimeUnit.DAYS.toMillis(1)));
long startTime = System.currentTimeMillis();
// Below mod function gets code to start of the day
long lastStart = startTime - (startTime % (TimeUnit.DAYS.toMillis(1)));
long now = System.currentTimeMillis();
long minuteInMs = TimeUnit.MINUTES.toMillis(1);
countOfMinutes = (now - lastStart) / minuteInMs;
这是我24/7运行并定期重新启动的代码片段。我在输出中记录了“lastStart”值、“now”值和“countOfMinutes”值。我在本地计算机上使用了相同的值,得到了预期值。但是当查看日志时,这些相同的值会导致0。我不明白为什么相同的数字会导致不同的值
以下是我从运行的系统中获得的日志:
18:21:53.908 INFO [Thread-3] Adjusted start time= 1550102400000\n
18:21:53.908 INFO [Thread-3] Current time= 1550168520001\n
18:21:53.908 INFO [Thread-3] countOfMinutes based on start time= 0\n
所以我取了这些值并在本地运行,得到了我所期望的:
14:52:17.037 [main] INFO The difference is:66120001
14:52:17.041 [main] INFO value of countOfMinutes:1102
我在想一些溢出的事情,但只是不确定这怎么可能在某些时候发生。我不怀疑日志会像这样损坏,long的toString()方法显示了一件事,而实际上是另一件事
已编辑:使用实际代码更新
注意:实际代码中已经有我认为应该更新的东西。e、 g.记录lastStart而不是startTime(如果我将在计算中使用它),立即存储,然后立即记录,而不是多次调用System.currentTime等。我想记录的变量值和实际变量值(我们不知道)之间的差异可能会导致这种情况,但这似乎很奇怪。
代码如下:
long startTime = System.currentTimeMillis();
long lastStart = startTime - (startTime % (TimeUnit.DAYS.toMillis(1)));
startTime = lastStart;
logger.info("Adjusted start time= {}", startTime); // Adjust start time to start of the day
long minuteInMs = TimeUnit.MINUTES.toMillis(1);
logger.info("Current time= {}", System.currentTimeMillis());
long now = System.currentTimeMillis();
long countOfMinutes = (now - lastStart) / minuteInMs;
logger.info("countOfMinutes based on start time= {}", countOfMinutes);
那么,错误显然在日志记录中。日志记录是准确的,因为当它的值为0时,会发生后续代码,我可以看到这些行被反复执行,直到达到正确的计数。所以它实际上是0。日志记录中的错误可能在currentTime或startTime中,但似乎不太可能。这是随机发生的,一周发生几次,所以它超过一个小时anomaly@Kirit用synchronized包装它们并移除volatile。因为,计算分钟计数的逻辑在线程内存中。易失性变量直接存储在系统的主内存中,可由多个线程访问。您需要向我们显示导致此问题的实际代码,包括写入日志消息的实际代码。另外,我假设您已经检查/再次检查了生产环境中运行的代码是否与您正在查看的源代码(!)Re-Sivaraj的评论相匹配。“…并且可以由多个线程访问”。它们可以被多个线程访问和更新。。。导致竞态条件。错误显然存在于日志记录中。日志记录的准确性在于,当其值为0时,会出现后续代码,我可以看到这些行被反复执行,直到达到正确的计数。所以它实际上是0。日志记录中的错误可能在currentTime或startTime中,但似乎不太可能。这是随机发生的,一周发生几次,所以它超过一个小时anomaly@Kirit用synchronized包装它们并移除volatile。因为,计算分钟计数的逻辑在线程内存中。易失性变量直接存储在系统的主内存中,可由多个线程访问。您需要向我们显示导致此问题的实际代码,包括写入日志消息的实际代码。另外,我假设您已经检查/再次检查了生产环境中运行的代码是否与您正在查看的源代码(!)Re-Sivaraj的评论相匹配。“…并且可以由多个线程访问”。它们可以被多个线程访问和更新。。。导致比赛条件。