簡體   English   中英

Java多線程

[英]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);
    }

}

一些注意事項:

  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/

您錯過的唯一一件事就是每秒鍾更新一次標簽。 通過使用系統日期計算時間的線程工作正常。 您可以做的是每秒鍾引發一個事件,然后在事件的偵聽器中更改文本字段的值。

創建一個TimerTask並在計時器的run方法中調用setText 然后安排要每秒執行的任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM