簡體   English   中英

如何使線程等待另一個類的方法完成

[英]How to make thread wait untill method of another class completes

這是我的示例代碼:

package javaapplication35;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import static javaapplication35.ProgressBarExample.customProgressBar;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class ProgressBarExample {

final static JButton myButton =new JButton("Start");
final static JProgressBar customProgressBar = new JProgressBar();
private static final JPanel myPanel = new JPanel();

public static void main(String[] args) {
    customProgressBar.setMaximum(32);
    customProgressBar.setStringPainted(true);
    myPanel.add(customProgressBar);
    myPanel.add(myButton);

    myButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e)
        {

            Thread firstly =new Thread(new Runnable (
            ) {
                @Override
                public void run() {
                    Calculations a = new  Calculations();
                    a.doCaculations();
                }
            });          

            Thread secondly =new Thread(new Runnable (
            ) {
                @Override
                public void run() {
                    JOptionPane.showMessageDialog(null,"just finished");
                }
            }); 

            firstly.start();
            try {
                firstly.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(ProgressBarExample.class.getName()).log(Level.SEVERE, null, ex);
            }


            secondly.start(); 
        }
    });          

    JOptionPane.showMessageDialog(null, myPanel, "Progress bar test", JOptionPane.PLAIN_MESSAGE);

 }

}

class Calculations {
public void doCaculations() {

     new SwingWorker<Void, Void>() {
        @Override
        protected Void doInBackground() throws Exception {
            int value = 0;
            while (value < customProgressBar.getMaximum()) {
                Thread.sleep(250);
                value ++;
                customProgressBar.setValue(value);
            }
            return null;
        }
    }.execute();
}   

 private void doOtherStaff(){
    //more methods, that don't need to run in seperate threads,  exist
 }

}

有2個線程。 firstly線程創建一個CalculationsdoCaculations() ,然后在其上運行doCaculations()方法。 secondly線程彈出一條消息。

我的“真實”代碼中的doCaculations()方法執行了一些耗時的數學doCaculations()並且為了模擬花費的時間,我添加了Thread.sleep(250); 我需要告知用戶計算的進度,因此我使用的是由doCaculations()方法更新的doCaculations()

我試圖做的方式代碼工作的secondly線程運行后firstly線程結束。 但是我無法使其工作。 發生的情況是該彈出消息立即彈出(這意味着它在我希望它運行之前就已線程運行)。

注意:“剛剛完成”消息只是為了測試代碼。 在我的“真實”程序中,將使用一種方法。 我做這個筆記是因為如果我只想顯示一條消息,可以將其放在doCaculations()方法的末尾,那么一切都會正常進行。

我知道線程處理一定做錯了,但是找不到。 有任何想法嗎?

PS:一個想法:實際上doCaculations()方法有其自己的線程。 因此,它“在線程內的SwingWorker中運行”。 首先猜測Igues.join firstly.join(); 正常工作。 但是,在doCaculations()方法之后,認為第fistrly線程已完成,這就是代碼繼續執行secondly線程的原因,而不知道doCaculations()線程仍在執行某些操作。

嘗試

a.doCaculations();
a.join();

編輯:
由於您使用的是SwingWorker,因此我先前的回答是錯誤的,但是正如您所評論的那樣,您已經擴展了Thread,以下內容將為您工作:

Thread a = new Calculations();
a.start();
a.join();

別忘了,您必須重寫Calculations類中的run方法,例如:

class Calculations extends Thread {
    @Override
    public void run() {
        //your code here
    }    
}

在Java中,您可以使用swingworker,並在done()方法中調用Dialog

在android中,您可以使用AsyncTask調用新線程,並在OnPostExecute方法中調用show message對話框。

您的Calculations類必須擴展SwingWorker。 您可以在doInBackground()計算

public class Calculations extends SwingWorker<Void, Void>{

    @Override
    protected Void doInBackground() throws Exception {
        System.out.println("Calculating.");
        Thread.sleep(3000);
        return null;
    }
}   

actionPerformed()您可以使用這樣的Calculations。

    public void actionPerformed(ActionEvent e)
    {
      //FISRT run method
      Calculations a = new  Calculations();
      a.execute(); // Start calculations
      try {
        a.get(); // Wait for calculations to finish
      } catch (InterruptedException | ExecutionException e1) {
        e1.printStackTrace();
      }
      //THEN inform that just finished
      JOptionPane.showMessageDialog(null,"just finished");
    }

編輯:如果您有多種方法想要在SwingWorker中運行,則可以使代碼幾乎保持原樣。 但是只添加這些行。

public class Calculations{
    protected void calculate() {
        SwingWorker sw = new SwingWorker(){
            @Override
            protected Object doInBackground() throws Exception {
                System.out.println("Calculating.");
                Thread.sleep(3000);
                return null;
            }
        };
        sw.execute(); //Start
        try {
            sw.get(); //Wait
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

在每種Calculations方法中,您都像創建新的SwingWorker一樣,並通過調用SwingWorker.get();等待其完成SwingWorker.get();

暫無
暫無

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

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