java - Thread.sleep() 的效率

标签 java multithreading thread-sleep coding-efficiency

我这里有一些代码可以按照我想要的方式工作。它只是我在代码中确定的特定日期的倒计时(以秒为单位)。我正在使用Thread.currentThread().sleep(1000);将 JLabel 更新为距日期还剩的当前时间。问题是 JLabel 并没有像预期的那样每秒刷新一次。有时每 2 秒更新一次,有时则需要整整 10 秒才能更新。我相信这与我调用方法的方式有关,但我不太确定如何使其更有效。

下面是调用线程内更新 JLabel 的方法的 main 方法:

public static void main(String args[])
{
    initUI();
    try
    {
        while(true)
        {
            Thread.currentThread().sleep(1000);
            getTime();
        }
    } catch(Exception e){System.out.println("An error has occured...");}
}

这里是main方法调用的方法。该方法最终将剩余秒数变量发送给第三个方法:

public static void getTime()
{
    Calendar c = Calendar.getInstance();
    // Gets abstract current time in ms
    long now = c.getTimeInMillis();

    c.set(Calendar.HOUR_OF_DAY, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 0);

    // Gets current time in ms
    long msPassed = now - c.getTimeInMillis();
    // There are 86,400,000 milliseconds in a day
    // Gets the seconds remaining in the day
    long secRemaining = (86400000 - msPassed) / 1000;

    //-----------------------------------------------------// 
    // Creates a new calendar for today
    Calendar cal = Calendar.getInstance();
    int currentDayOfYear = cal.get(Calendar.DAY_OF_YEAR);

    // Creates a calendar for November 20th, 2016
    Calendar aniv = new GregorianCalendar(2016,10,20);
    aniv.set(Calendar.MONTH, 10);
    aniv.set(Calendar.DAY_OF_MONTH, 20);
    int aniversary = aniv.get(Calendar.DAY_OF_YEAR);

    remaining = ((aniversary - currentDayOfYear) * 24 * 60 * 60) + secRemaining;
    setTextOnScreen(remaining);
}

最后,这是重写 JLabel 的方法(由上面的方法调用):

public static void setTextOnScreen(long num)
{
    text.setForeground(Color.GREEN);
    text.setLocation((int)width/2 - 150, 50);
    text.setFont(new Font("Monospaced", Font.BOLD, 48));
    text.setSize(300,150);

    text.setText("" + num);
    panel.add(text);
}

我没有包含其余的代码,因为它应该是无关紧要的,但如果您也想看到它,请告诉我。

最佳答案

两个问题:

  1. 您正在从后台线程调用 text.setSomething()panel.add,这不是您应该使用的 UI 线程。尝试使用 SwingUtils.invokeLater()SwingUtils.invokeAndWait() 并调用接触 UI 的代码。

  2. 调用 set 方法后,您还应该调用 text.invalidate() 来表明 UI 组件需要更新...否则UI线程不会注意到组件需要重新测量和重绘。

关于java - Thread.sleep() 的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39857604/

相关文章:

Java OutOfMemory 仅在 Linux 环境下

java - 当executor遇到Thread.sleep时,为什么线程没有 hibernate 就结束或者抛出InterruptedException?

Java线程在多个计时器上触发

java - 在 Java EE 环境中暂停/ sleep n 秒

java - 如何使用 ScheduledExecutorService 在一周中的每个星期五随时运行特定任务?

java - 需要了解java中的thread(this,ThreadName)吗?

java - 在 Java 中将表数据读入二维数组

java - Kotlin 中的简单继承示例

java - 拆分段落中的每个字符串

multithreading - Silverlight - 在从方法返回之前等待异步调用完成