[英]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
線程創建一個Calculations
類doCaculations()
,然后在其上運行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.