用JFrame实现Java中的简单时钟

用JFrame实现Java中的简单时钟,java,multithreading,swing,Java,Multithreading,Swing,我一直在摆弄NetBeans,创建一个始终位于屏幕右下角的时钟。我已经完成了它,但我认为我的代码正在消耗内存,在我把它放了一夜之后,我又回到了1.4GB的内存和大量CPU的使用。我是Java编程新手,所以我希望这不正常 在我的主线程中,每次运行我都会创建一个新的日历对象。将其移出线程将创建一个日历对象,该对象使用当前时间初始化,但从不更新,有更好的方法吗 我不习惯与线程打交道,我想我可能已经转过身来了。有谁能建议对以下方面进行改进,以降低我的内存占用和cpu使用率 public JavaCloc

我一直在摆弄NetBeans,创建一个始终位于屏幕右下角的时钟。我已经完成了它,但我认为我的代码正在消耗内存,在我把它放了一夜之后,我又回到了1.4GB的内存和大量CPU的使用。我是Java编程新手,所以我希望这不正常

在我的主线程中,每次运行我都会创建一个新的日历对象。将其移出线程将创建一个日历对象,该对象使用当前时间初始化,但从不更新,有更好的方法吗

我不习惯与线程打交道,我想我可能已经转过身来了。有谁能建议对以下方面进行改进,以降低我的内存占用和cpu使用率

public JavaClockGUI() {
    initComponents();    

    new Thread()
    {
        public void run()
        {
            while(true) 
            {
                Calendar cal = new GregorianCalendar();
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int min = cal.get(Calendar.MINUTE);
                int sec = cal.get(Calendar.SECOND);

                String time = String.format("%02d",hour) + ":" + String.format("%02d",min) + ":" + String.format("%02d",sec);

                lblTime.setText(time);
            }
        }
    }.start();
}

尝试在while循环之外声明变量 以及在给定的时间量上具有延迟以减少循环的执行

public void run()
    {
        Calendar cal;
        int hour;
        int min;
        int sec;
        String time;
        while(true) 
        {
            cal = new GregorianCalendar();
            hour = cal.get(Calendar.HOUR_OF_DAY);
            min = cal.get(Calendar.MINUTE);
            sec = cal.get(Calendar.SECOND);

            String time = String.format("%02d",hour) + ":" +  String.format("%02d",min) + ":" + String.format("%02d",sec);

            lblTime.setText(time);
            //delay the loop for 1 sec
            try {
                Thread.currentThread().sleep(1000);
                System.out.println(x);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }

希望这对你有帮助

Date(){
    DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss)";
    Date date = new Date();
    boolean condition = false;

    while(!false){
      lbltime.setText(dateFormat.format(date));
      Thread.sleep(1000);
   }
}

性能有两个重要方面:

  • 不要每次迭代都在循环中创建新对象(并尽可能避免堆分配)
  • 定期执行任务(不要让
    while(true)
    循环猖獗运行)
我不知道最好的方法是什么,但我有一个简短、简单、准确的方法:

使用
定时器
以固定速率执行
定时器任务
。该方法将以相对于绝对时间的固定速率执行任务(
run
method),而不是相对于上一次执行。也就是说,如果其中一个执行被延迟,那么下一个执行将开始,而不管延迟如何(它们之间的间隔将更短)。调用
Thread.sleep(1000)
将不会以这种方式运行,并将导致长期累积延迟

为了接收时间并对其进行格式化,Java8日期时间API(
java.time
)是一个不错的选择

public class Example {

    public static void main(String[] args) {

        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
        new Timer().scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {

                System.out.println(LocalTime.now().format(formatter));
            }
        }, 0, 1000);
    }
}
注释

  • 如果您不喜欢这里的匿名构造,可以让类扩展
    TimerTaks
    ,或者创建一个内部类
  • 如果您不需要此格式,请浏览
    DateTimeFormatter
    ,以找到所需的格式
  • 您可以保存对计时器的引用

    Timer timer = new Timer();
    timer.scheduleAtFixedRate(...);
    
    如果你以后需要的话


Try replace Thread by Timer TaskSwing Timer是一种更简单的方法,它基于snipper,以CPU能提供的速度执行
run()
方法中的
while循环。这并不是真正需要的,因为秒数变化不太频繁。;-)或者你错过了发布定期调用的代码吗?@次优我认为这是我的代码的主要问题,我正在尽可能快地运行它。不幸的是,我没有遗漏这一点。谢谢你的其他建议。我现在将做一些研究。我在哪里定义线程?我当前的方法将线程定义为包装运行,因此我无法在线程内部休眠线程。我不认为……啊,是的,我认为这就是我需要的。我试过了,我已经一路降到了25mb,我想这是编译器的开销。我现在遇到的唯一问题是,我试图在静态void main中运行
lblText.setText(LocalTime.now().format(formatter))
,但我得到了一个非静态变量静态上下文错误。有没有一种简单的解决方法?
static
的问题是Java中与程序总体设计相关的一个基本概念。这也与这个问题无关。看吧,也许吧。您可能需要将标签设置为静态。非常感谢您让我知道。我试着投票,但我还没有代表。我也不确定是否接受这个答案,因为我仍然停留在最后一部分。谢谢你让我知道。如果你被编译器关于
static
的错误所困扰,那就用一个。如果您需要关于本页中问题的澄清或帮助,请询问。