[英]Multithreading in 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中運行線程,但是我想要一些解決此問題的方法。
問題是您只閱讀一次時間。 您應該啟動一個查詢LocalTime
的輔助線程,或者向LocalTime
添加一個偵聽LocalTime
,該偵聽LocalTime
會通知時間更改並觸發標簽更新。
附帶說明:您可能希望將new Date()
與SimpleDateFormat
結合使用,以獲取格式正確的表示形式。
拜托,請使用計時器執行此類任務...為什么要增加所有這些額外的復雜性? 嘗試這樣的事情:
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();
除非您不包括關鍵的代碼段,否則無法多次更新標簽。
看,您的自定義線程每秒鍾踢一次,更新它自己的this.currentTime
字段。
但是,您的標簽(至少使用您所顯示的少量代碼),只會使用當時時間字段中的 l
進行一次更新(通過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);
}
}
一些注意事項:
synchronized
關鍵字。 供您閱讀的資料:
Swing中的並發http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#event_dispatching
並發性(Java教程) http://download.oracle.com/javase/tutorial/essential/concurrency/
您錯過的唯一一件事就是每秒鍾更新一次標簽。 通過使用系統日期計算時間的線程工作正常。 您可以做的是每秒鍾引發一個事件,然后在事件的偵聽器中更改文本字段的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.