Java 中的多线程
大家好
我在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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
问题是你只读了一次时间。您应该启动一个查询
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 toLocalTime
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 aSimpleDateFormat
in order to get a nicely formatted representation.除非您不包含关键代码片段,否则标签无法多次更新。
看,您的自定义线程每秒都在启动,更新它自己的
this.currentTime
字段。但是你的标签(至少使用你所显示的少量代码),它只会更新一次(通过
this.jLabel1.setText(l.getCurrentTime())
),无论我
在那一刻在它的时间字段中。仅仅因为本地时间线程运行,并不意味着它会神奇地出去并更新标签。如果您不自己编写代码,为什么它会神奇地做到这一点?想一想。
您需要做的是让线程在其 run 方法中更新标签本身。此外,这应该在 Swing 线程规则内(以及在事件队列中)完成。如何重构它以获得干净的代码,这是另一个线程的主题。
一些注意事项:
synchronized
关键字。供您阅读的内容:
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 whateverl
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.
Some notes:
synchronized
keyword in this specific instance of your run() method.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/
请使用 Timer 类型任务...为什么要搞那么多额外的复杂性?
尝试这样的事情:
Please, please use a Timer for that kind of task... Why go to all that extra complexity?
Try something like this:
创建一个 TimerTask 并调用 setText 在计时器的 run 方法中。然后 安排每秒执行一次的任务。
Create a TimerTask and call the setText in timer's run method. Then schedule the task to be executed every second.
您唯一缺少的一件事就是每秒更新标签。使用系统日期计算时间的线程工作正常。你可以做的是每秒引发一个事件并更改事件侦听器中文本字段的值。
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.