Java 中的多线程

发布于 2024-11-02 11:54:38 字数 1360 浏览 0 评论 0原文

大家好
我在java中的多线程方面遇到了问题。这是我的场景。我有一个类,名称是 LocalTime。这个类应该捕获系统的当前时间,并通过一个名为 getCurrentTime 的方法,将该值返回到 Form。这是这个类的代码

public class LocalTime implements Runnable {

 private String currentTime=null;
 Thread t;
 private long time;
 private long h;
 private long m;
 private long s;
 public LocalTime() {
    t=new Thread(this,"current Time");
    t.start();

 }

 public synchronized void run() {

    try {
        for(;;){
        Thread.sleep(1000);
                    time = System.currentTimeMillis()/1000;
                    h = (time / 3600) % 24;
                    m = (time / 60) % 60;
                    s = time % 60;
                    this.currentTime=h+":"+m+":"+s;
        }
     } catch (InterruptedException ex) {
        Logger.getLogger(LocalTime.class.getName()).log(Level.SEVERE, null, ex);
     }

 }
 public String getCurrentTime(){
     return  this.currentTime;
 }

}

这是主窗体的代码:

public MainForm1() {
    initComponents();
    LocalTime l=new LocalTime();
    this.jLabel1.setText(l.getCurrentTime());//show the current time
    //The rest of code
}


现在我的主要问题是显示当前系统时间的 jLabel1 文本不会每 1 秒更新一次。如果我在 jLabel1.setText(l.getCurrentTime()) 行之前插入 for(;;) ,则其余代码将无法访问。我应该怎么纠正这个错误?请根据这些假设建议我解决方案。我知道我也可以在 MainForm1 中运行线程,但我想要解决这个问题。

Hey all
I have a problem with multithreading in java. This is my scenario. I have a class,which name is LocalTime. This class should catch the current time of system, and via a method,which name is getCurrentTime, return this value to a Form. This is the code of this class

public class LocalTime implements Runnable {

 private String currentTime=null;
 Thread t;
 private long time;
 private long h;
 private long m;
 private long s;
 public LocalTime() {
    t=new Thread(this,"current Time");
    t.start();

 }

 public synchronized void run() {

    try {
        for(;;){
        Thread.sleep(1000);
                    time = System.currentTimeMillis()/1000;
                    h = (time / 3600) % 24;
                    m = (time / 60) % 60;
                    s = time % 60;
                    this.currentTime=h+":"+m+":"+s;
        }
     } catch (InterruptedException ex) {
        Logger.getLogger(LocalTime.class.getName()).log(Level.SEVERE, null, ex);
     }

 }
 public String getCurrentTime(){
     return  this.currentTime;
 }

}

and this is the code of main form:

public MainForm1() {
    initComponents();
    LocalTime l=new LocalTime();
    this.jLabel1.setText(l.getCurrentTime());//show the current time
    //The rest of code
}

now my major problem is the jLabel1 text which shows current system time does not update each 1 second. If I insert for(;;) before the line of jLabel1.setText(l.getCurrentTime()) the rest of code won't be reacheable. what should I to correct this error? please suggest me solution with these assumptions. I know that I can run a thread in MainForm1, too but I want some solution to this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心舞飞扬 2024-11-09 11:54:38

问题是你只读了一次时间。您应该启动一个查询 LocalTime 的工作线程,或者向 LocalTime 添加一个侦听器,以通知时间更改并触发标签更新。

附带说明:您可能希望将 new Date()SimpleDateFormat 结合使用,以获得格式良好的表示形式。

The problem is that you just read the time once. You should either start a worker thread that queries LocalTime or add a listener to LocalTime that is informed of time changes and triggers the label update.

As a side note: you might want to use new Date() in conjunction with a SimpleDateFormat in order to get a nicely formatted representation.

墨离汐 2024-11-09 11:54:38

除非您不包含关键代码片段,否则标签无法多次更新。

看,您的自定义线程每秒​​都在启动,更新它自己的 this.currentTime 字段。

但是你的标签(至少使用你所显示的少量代码),它只会更新一次(通过 this.jLabel1.setText(l.getCurrentTime())),无论 在那一刻在它的时间字段中。

仅仅因为本地时间线程运行,并不意味着它会神奇地出去并更新标签。如果您不自己编写代码,为什么它会神奇地做到这一点?想一想。

您需要做的是让线程在其 run 方法中更新标签本身。此外,这应该在 Swing 线程规则内(以及在事件队列中)完成。如何重构它以获得干净的代码,这是另一个线程的主题。

// java pseudocode

public void run() {

    Runnable labelUpdater = new Runnable()
    {
      public void run()
      {
        someForm.jLabel1.setText(yourUpdatedTimeFormattedAsStringOrWhatever);
      }
    }
    try {
        for(;;){
           Thread.sleep(1000);
           // will cause label update to occur in the awt event queue
           SwingUtils.invokeLater(labelUpdater); 
        }
    } catch (InterruptedException ex) {
        Logger.getLogger(LocalTime.class.getName()).log(Level.SEVERE, null, ex);
    }

}

一些注意事项:

  1. 在 run() 方法的这个特定实例中,您不需要 synchronized 关键字。
  2. 使用 java.util.Calendar 和 java.util.Format 获取当前时间的字符串表示形式。您在那里所做的所有字符串连接和除法 System.currentTimeMillis() 的输出都是很糟糕的。您是否查看过 Java API 以了解已有的内容??????????

供您阅读的内容:

Swing 中的并发
http://java.sun.com/products/jfc /tsc/articles/threads/threads1.html#event_dispatching

并发(Java 教程)
http://download.oracle.com/javase/tutorial/essential/concurrency/

Unless you are not including crucial pieces of code, there is no way for the label to be updated more than once.

See, your custom thread is kicking every second, updating it's own this.currentTime field.

But your label (at least with the meager amount of code that you are showing), it only gets updated once (via this.jLabel1.setText(l.getCurrentTime())) with whatever l had in it's time field at that moment.

Just because the local time thread runs, that doesn't mean it will magically go out and update the label. Why would it magically do it if you don't code that yourself? Think about it.

What you need to do is to have the thread update the label itself within it's run method. Moreover, this should be done within the Swing thread rules (and in the event queue) How you refactor that so that you get clean code, that's a topic for another thread.

// java pseudocode

public void run() {

    Runnable labelUpdater = new Runnable()
    {
      public void run()
      {
        someForm.jLabel1.setText(yourUpdatedTimeFormattedAsStringOrWhatever);
      }
    }
    try {
        for(;;){
           Thread.sleep(1000);
           // will cause label update to occur in the awt event queue
           SwingUtils.invokeLater(labelUpdater); 
        }
    } catch (InterruptedException ex) {
        Logger.getLogger(LocalTime.class.getName()).log(Level.SEVERE, null, ex);
    }

}

Some notes:

  1. You don't need the synchronized keyword in this specific instance of your run() method.
  2. Use java.util.Calendar and java.util.Format to get string representations of the current time. What you are doing there with all that string concatenation and dividing the output of System.currentTimeMillis() is just bad. Have you looked at the Java API to see what's already there for you????????

Stuff for you to read:

Concurrency in Swing
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#event_dispatching

Concurrency (the Java Tutorial)
http://download.oracle.com/javase/tutorial/essential/concurrency/

〃温暖了心ぐ 2024-11-09 11:54:38

请使用 Timer 类型任务...为什么要搞那么多额外的复杂性?
尝试这样的事情:

  int delay = 1000; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
     final LocalTime locTime = new LocalTime();
     public void actionPerformed(ActionEvent evt) {
         jLabel1.setText(locTime.getCurrentTime());
     }
  };
  new Timer(delay, taskPerformer).start();

Please, please use a Timer for that kind of task... Why go to all that extra complexity?
Try something like this:

  int delay = 1000; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
     final LocalTime locTime = new LocalTime();
     public void actionPerformed(ActionEvent evt) {
         jLabel1.setText(locTime.getCurrentTime());
     }
  };
  new Timer(delay, taskPerformer).start();
水波映月 2024-11-09 11:54:38

创建一个 TimerTask 并调用 setText 在计时器的 run 方法中。然后 安排每秒执行一次的任务。

Create a TimerTask and call the setText in timer's run method. Then schedule the task to be executed every second.

记忆で 2024-11-09 11:54:38

您唯一缺少的一件事就是每秒更新标签。使用系统日期计算时间的线程工作正常。你可以做的是每秒引发一个事件并更改事件侦听器中文本字段的值。

There is only one thing that u are misssing is to update the label after each second. the thread which is calculating the time by using system date is working fine. What u can do is raise an event after each second and change the value of textfield in the listener of the event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文