为啥 Java 中有两个 Timer 类(一个在 javax.swing 下,一个在 java.util 下)?

Posted

技术标签:

【中文标题】为啥 Java 中有两个 Timer 类(一个在 javax.swing 下,一个在 java.util 下)?【英文标题】:Why are there two Timer classes in Java(one under javax.swing, one under java.util )?为什么 Java 中有两个 Timer 类(一个在 javax.swing 下,一个在 java.util 下)? 【发布时间】:2013-03-11 12:01:42 【问题描述】:

我对此感到非常困惑。 Java 有两个 Timer 类,一个在 swing 下,一个在 util 下……这是为什么呢?如果我只想每 Y 秒运行一次 X,我应该使用哪一个?这是否意味着如果我正在构建一个 GUI,我必须使用 swing 版本的计时器?

谢谢!

【问题讨论】:

好奇:为什么是赏金?答案尽可能完整/正确:-) 不确定您是否感兴趣,但Quartz 是一个非常好的工作调度库。 【参考方案1】:

这里是javax.swing.Timer和java.util.Timer的区别:

javax.swing.Timer
适用于更简单的情况,使用较少数量的计时器(比如少于十二个) 在事件调度线程上运行 ActionListener 对象 可以直接更新GUI,无需使用EventQueue.invokeLater 如果任务完全在事件分派线程中运行(也就是说,如果它没有产生工作线程),那么 GUI 将仅在任务不花费很长时间(例如 300 毫秒以下)时保持响应李>

java.util.Timer

比 javax.swing.Timer 更具可扩展性,并具有额外的调度功能 在私有线程上运行 TimerTask 对象 需要使用 EventQueue.invokeLater 来更新 GUI

您可以通过两种方式使用 Swing 计时器:

在延迟后执行一次任务。 例如,工具提示管理器使用 Swing 计时器来确定何时显示工具提示以及何时隐藏它。 重复执行一项任务。 例如,您可以执行动画或更新显示目标进度的组件。

这里是上述信息的来源http://www.javapractices.com/topic/TopicAction.do?Id=160和http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

如果我只想每 Y 秒运行一次 X,我应该使用哪一个?

取决于您正在与之交互的内容。如果您正在与 GUI 交互,则使用 javax.swing.Timer ,否则使用 java.util.Timer

这是否意味着如果我要构建 GUI,我必须使用 swing 版本 计时器?

是的

【讨论】:

@Adel 您应该考虑 Executor 服务框架(如果在 Java 5 或更高版本上)而不是 java.util.Timer。如果您需要与 GUI 交互,请使用 javax.swing.Timer 但尽量避免使用它,因为它在 GUI 线程上运行(尤其是对于冗长的操作)。也看看这个问题:Java Timer vs ExecutorService +1。这次真是万分感谢。 Java 文档在提及差异时非常混乱。【参考方案2】:

Swing 版本用于渲染 Swing 组件。如果您只是需要时间,请使用 util。

【讨论】:

【参考方案3】:

你说的很对。建议如果你要做的 UI 工作会受到计时器的影响,你应该使用 swing 组件。 util timer 不能自行设置 UI 元素。 Here is a nice comparison.

【讨论】:

【参考方案4】:

在 v 1.3 中,另一个 Timer 类被添加到 Java 平台: java.util.Timer。 it 和 javax.swing.Timer 都提供相同的基本功能 功能,但 java.util.Timer 更通用,有更多 特征。 javax.swing.Timer 有两个特性可以使它成为 更容易与 GUI 一起使用。首先,它的事件处理比喻是 熟悉 GUI 程序员并且可以处理 事件调度线程更简单一些。二、它的自动线程 共享意味着您不必采取特殊步骤来避免 产生太多线程。相反,您的计时器使用相同的线程 用于使光标闪烁、工具提示出现等。

您可以找到更多文档和几个使用示例 通过访问 Java 教程中的“如何使用定时器”部分来创建定时器。 有关在此 Timer 类和 java.util.Timer,请参阅在 Swing 应用程序中使用计时器,文章 摆动连接。

来自official documentation。

【讨论】:

【参考方案5】:

如果你有一个简单快速的任务需要与swing框架交互,那么使用javax.swing.Timer会更简单

对于几乎所有其他情况 - 即使是 GUI 应用程序,您也应该使用 java.util.Timer 如果你有一个 GUI,那么你必须像上面提到的那样使用 EventQueue.invokeLater 更新 GUI 来处理与 swing 事件调度线程的集成

通常,当您开始时,最初的几个计时器事件可能看起来很快并且不太可能影响性能,但随着需求的变化,它们会花费更长的时间并且会出现更多,并且 GUI 本身的需求也会增加。最好的做法是通过在 swing 环境之外启动来避免返工 - 否则您的 GUI 将很快出现“迟钝”或“无法使用”

【讨论】:

以上是关于为啥 Java 中有两个 Timer 类(一个在 javax.swing 下,一个在 java.util 下)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 xmlignore 不能与 System.Timers.Timer 类一起使用

为啥你不能在 Java 中有一个受保护的抽象类?

Java定时任务:利用java Timer类实现定时执行任务的功能

详解java定时任务---Timer篇

Timer的schedule和scheduleAtFixedRate方法的区别解析

在你的类中有两个 System.Timer.Timer 对象并捕获异常