首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Thread.sleep()提高效率

使用Thread.sleep()提高效率
EN

Stack Overflow用户
提问于 2016-10-05 00:39:02
回答 3查看 614关注 0票数 0

我这里有一些代码,它的工作方式与我想要的一样。它只是我在代码中确定的特定日期的倒计时。我正在使用Thread.currentThread().sleep(1000);更新一个JLabel,其中包含到该日期之前的当前时间。问题是JLabel并不像它应该的那样每秒刷新一次。有时它每2秒更新一次,有时需要整整10秒才能更新。我相信这与我调用方法的方式有关,但我不太确定如何使其更有效。

下面是main方法,它调用该方法来更新线程中的JLabel:

代码语言:javascript
复制
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方法调用的方法所调用的方法。此方法最终将剩余秒数变量发送到第三个方法:

代码语言:javascript
复制
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的方法(由上面的方法调用):

代码语言:javascript
复制
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);
}

我没有包括其余的代码,因为它应该是不相关的,但如果你也想看看,请让我知道。

EN

回答 3

Stack Overflow用户

发布于 2016-10-05 00:43:59

两个问题:

  1. 您正在从后台线程调用text.setSomething()panel.add,该线程不是您应该使用的UI线程。否则,UI线程不会注意到组件需要重新测量和重新绘制。
票数 3
EN

Stack Overflow用户

发布于 2016-10-05 00:43:51

您应该只更新Event Loop中的GUI组件。如果你试图在其他线程中更新它们,你可能会得到不可预知的结果。我建议对要在GUI事件循环中运行的周期性任务使用swing计时器。

票数 1
EN

Stack Overflow用户

发布于 2016-10-05 00:48:13

您可以尝试使用Timer

它有一个方法#scheduleAtFixedRate,该方法接受要执行的任务、开始执行任务的时间和运行任务的时间间隔。

将您计划的操作包装到一个类中,该类扩展了TimerTask以使用此方法。

下面是Java7 https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html中该类的javadoc

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39857604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档