java invokelater 以及invokeandwait

來源:互聯網
上載者:User

標籤:

SwingUtilities中invokeLater和invokeAndWait介紹
   在Java中Swing是線程不安全的,是單線程的設計,這樣的造成結果就是:只能從事件派發線程訪問將要在螢幕上繪製的Swing組件。事件派發線程是調用paint和update等回調方法的線程,它還是事件監聽器介面中定義的事件處理方法,例如,ActionListener中的actionPerformed方法在事件派發線程中調用。
   Swing是事件驅動的,所以在回呼函數中更新可見的GUI是很自然的事情,比如,有一個按鈕被按下,項目列表需要更新時,則通常在與該按鈕相關聯的事件監聽器的actionPerformed方法中來實現該列表的更新,從事件派發線程以外的線程中更新Swing組件是不正常的。
   有時需要從事件派發線程以外的線程中更新Swing組件,例如,在actionPerformed中有很費時的操作,需要很長時間才能返回,按鈕啟用後需要很長時間才能看到更新的列表,按鈕會長時間保持按下的狀態只到actionPerformed返回,一般說來耗時的操作不應該在事件處理方法中執行,因為事件處理返回之前,其他事件是不能觸發的,介面類似於卡住的狀況,所以在獨立的線程上執行比較耗時的操作可能更好,這會立即更新使用者介面和釋放事件派發線程去派發其他的事件。
   SwingUtilities類提供了兩個方法:invokeLate和invoteAndWait,它們都使事件派發線程上的可運行對象排隊。當可運行對象排在事件派發隊列的隊首時,就調用其run方法。其效果是允許事件派發線程調用另一個線程中的任意一個代碼塊。
   只有從事件派發線程才能更新群組件。
   程式樣本:更新群組件的錯誤方法
   startButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    GetInfoThread t = new GetInfoThread(Test.this);
    t.start();
    startButton.setEnabled(false);
   }
  });
  
  class GetInfoThread extends Thread {
 Test applet;

 public GetInfoThread(Test applet) {
  this.applet = applet;
 }

  public void run() {
   while (true) {
    try {
     Thread.sleep(500);
     applet.getProgressBar().setValue(Math.random() * 100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
 }
 錯誤分析:在actionPerformed中,監聽器把按鈕的允許狀態設定為false,由於是在事件派發線程上調用actionPerformed,所以setEnabled是一個有效操作,但是在GetInfoThread中設定進度條是一個危險的做法,因為事件派發線程以外的線程更新了進度條,所以運行是不正常的。

   1、invokeLater使用
    class GetInfoThread extends Thread {
  Test applet;
 
  Runnable runx;
 
  int value;

  public GetInfoThread(final Test applet) {
   this.applet = applet;
   runx = new Runnable() {
    public void run() {
     JProgressBar jpb = applet.getProgressBar();
     jpb.setValue(value);
    }
   };
  }

   public void run() {
    while (true) {
     try {
      Thread.sleep(500);
      value = (int) (Math.random() * 100);
      System.out.println(value);
      SwingUtilities.invokeLater(runx);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
  }
   
   2、invokeAndWait
   與invoikeLater一樣,invokeAndWait也把可運行對象排入事件派發線程的隊列中,invokeLater在把可啟動並執行對象放入隊列後就返回,而invokeAndWait一直等待知道已啟動了可啟動並執行run方法才返回。如果一個操作在另外一個操作執行之前必須從一個組件獲得資訊,則invokeAndWait方法是很有用的。
   class GetInfoThread extends Thread {
   Runnable getValue,setValue;
   int value,currentValue;
   public GetInfoThread(final Test applet){
   getValue=new Runnable(){
   public void run(){
    JProgressBar pb=applet.getProgressBar();
    currentValue=pb.getValue();
    }
   };
   setValue=new Runnable(){
    public void run(){
     JProgressBar pb=applet.getProgressBar();
     pb.setValue(value);
    }
   }
   }
   public void run(){
    while(true){
    try{
    Thread.currentThead().sleep(500);
    value=(int)(Math.random()*100);
    try{
    SwingUtilities.invokeAndWait(getValue);//直到getValue可啟動並執行run方法返回後才返回
      }catch(Exception ex){
      }
      if(currentValue!=value){
      SwingUtilities.invokeLater(setValue);
      }
     }
     }catch(Exception ex){
      }
    }
   }
   invokeLater和invoikeAndWait的一個重要區別:可以從事件派發線程中調用invokeLater,卻不能從事件派發線程中調用invokeAndWait,從事件派發線程調用invokeAndWait的問題是:invokeAndWait鎖定調用它的線程,直到可運行對象從事件派發線程中派發出去並且該可啟動並執行對象的run方法啟用,如果從事件派發線程調用invoikeAndWait,則會發生死結的狀況,因為invokeAndWait正在等待事件派發,但是,由於是從事件派發線程中調用invokeAndWait,所以直到invokeAndWait返回後事件才能派發。
   ex)actionPerformed();返回的時候事件派發線程才能派發線程,而在actionPerformed中使用invokeAndWait則會導致actionPerformed不能返回。所以也就無法派發invokeAndWait中的線程。

由於Swing是線程不安全的,所以,從事件派發線程之外的線程訪問Swing組件是不安全的,SwingUtilities類提供這兩種方法用於執行事件派發線程中的代碼

java invokelater 以及invokeandwait

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.