简体   繁体   English

使用Timer和TimerTask时的Java线程执行顺序

[英]Java thread execution order when using Timer and TimerTask

I'm using Timer as an process interrupt mechanism. 我将Timer用作进程中断机制。 The flow of logic is as follows: 逻辑流程如下:

T0: create new timer at T0 and schedule a new timer task to execute at T2 (1 second task delay, task is very simple - sets a flag variable) T0:在T0创建新计时器,并安排新的计时器任务在T2执行(任务延迟1秒,任务非常简单-设置标志变量)

T1: in the main calling thread, sleep for 5 seconds T1:在主调用线程中,睡眠5秒钟

T2: in the timer thread, task executes T2:在计时器线程中,任务执行

T5: sleep finishes T5:睡眠结束

T6: cancel timer and any scheduled tasks T6:取消计时器和任何计划的任务

The code works perfectly on my Windows and Ubuntu dev environment. 该代码可以在我的Windows和Ubuntu开发环境中完美运行。 But when I run the same code on my SLES 10 build server, logging indicates this execution order: 但是,当我在SLES 10构建服务器上运行相同的代码时,日志记录表明此执行顺序:

T0: timer and timer tasks are created to execute at T2 T0:创建计时器和计时器任务以在T2执行

T1: main thread sleeps for 5 seconds T1:主线程休眠5秒

T5: main thread wakes up T5:主线程唤醒

T6: timer cancels T6:计时器取消

T7: task executes T7:任务执行

Could anyone offer an explanation as to why this occurs? 谁能解释为什么会这样? Thanks very much. 非常感谢。

Hm. I'm surprised that you see that much difference (in seconds?), but I guess it is possible that you see different order of execution from machine to machine, jvm to jvm etc. Especially, when the JIT is compiling your code for the first time, I tend to see delay (compared to subsequent execution of same code) in the order of 100-300ms in my code for example, so maybe it's more dramatic in your code? 我很惊讶您看到这么多差异(以秒为单位?),但是我猜您可能会看到从机器到机器,从jvm到jvm等不同的执行顺序。尤其是当JIT为第一次,我倾向于在我的代码中看到大约100-300ms的延迟(与随后执行相同的代码相比),所以也许在您的代码中它更引人注目?

Not sure what you mean with "process interrupt mechanism". 不知道您所说的“进程中断机制”是什么。 Do you mean that the timer task interrupts some thread? 您是说定时器任务中断了某个线程吗?

Anyways, what I can suggest now is to use System.nanoTime() instead. 无论如何,我现在建议使用System.nanoTime()代替。 (Although I don't think it will explain anything, Use of System.currentTimeMillis() is discouraged in serious measurements). (尽管我认为它不会解释任何问题,但建议不要在严重的测量中使用System.currentTimeMillis() )。 Addition of -server to your JAVA_OPTS is generally advised so that you see the behavior when the code is optimized by JIT. 通常建议将-server到JAVA_OPTS中,以便您在通过JIT优化代码时看到行为。 It is also highly advisable to run your code multiple times and take statistics. 强烈建议您多次运行代码并进行统计。

If I were you, I'll do these small things first, then debug using synchronizers like CyclicBarrier , CountdownLatch and see where exactly the delay is coming. 如果您是我,我将首先做这些小事情,然后使用CyclicBarrierCountdownLatch类的同步器进行调试,并查看延迟的确切位置。

What are the "background noise" (degree of activity) in the SLES? SLES中的“背景噪音”(活动度)是多少? Maybe the OS is very very busy or something? 操作系统可能很忙还是什么?

What is the task's nature? 任务的性质是什么? Is it anything network/IO related? 网络/ IO相关吗?

It turned out it was a timestamp issue. 原来这是一个时间戳问题。 Using new Date().getTime instead of System.currentTimeMillis yielded the expected order of execution timestamps. 使用新的Date()。getTime而不是System.currentTimeMillis产生了预期的执行时间戳顺序。

Thanks for all the good ideas. 感谢所有的好主意。

You should consider firing an event when the tasks are complete. 您应该考虑在任务完成时触发事件。 That ensures execution order. 这样可以确保执行顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM