Java 如何使线程等待另一个类的方法完成

Java 如何使线程等待另一个类的方法完成,java,multithreading,thread-synchronization,Java,Multithreading,Thread Synchronization,下面是我的示例代码: 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; impo

下面是我的示例代码:

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
 }

}
PackageJavaApplication35;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入静态javaapplication35.ProgressBarExample.customProgressBar;
导入javax.swing.JButton;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.JProgressBar;
导入javax.swing.SwingWorker;
公共类进程就是一个例子{
最终静态JButton myButton=新JButton(“开始”);
最终静态JProgressBar customProgressBar=新JProgressBar();
private static final JPanel myPanel=new JPanel();
公共静态void main(字符串[]args){
customProgressBar.setMaximum(32);
customProgressBar.SetStringPaint(真);
myPanel.add(customProgressBar);
添加(myButton);
myButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e)
{
线程优先=新线程(新可运行(
) {
@凌驾
公开募捐{
计算a=新计算();
a、 文档();
}
});          
第二个线程=新线程(新可运行(
) {
@凌驾
公开募捐{
showMessageDialog(null,“刚刚完成”);
}
}); 
首先,开始();
试一试{
首先,join();
}捕获(中断异常例外){
Logger.getLogger(ProgressBarExample.class.getName()).log(Level.SEVERE,null,ex);
}
第二,开始();
}
});          
showMessageDialog(null,myPanel,“进度条测试”,JOptionPane.PLAIN_消息);
}
}
类计算{
公开作废文件(){
新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
int值=0;
while(值
有两条线。
首先
线程创建一个
计算
类INSACE,然后在其上运行一个
docuations()
方法。 第二个
线程弹出一条消息

我的“real”代码中的
docations()
方法执行一些耗时的数学运算,为了模拟花费的时间,我添加了
Thread.sleep(250)。我需要通知用户计算的进度,因此我使用的是progressbar,它由
doCaculations()
方法更新

我试图使代码以一种方式工作,
第二个
线程在
第一个
线程完成后运行。但我不能让它工作。发生的情况是,弹出消息立即弹出(这意味着它的线程运行在我希望它运行之前)

注意:“justfinished”消息只是为了测试代码。在我的“真实”程序中,一个方法将在它的位置。我之所以这样做是因为如果我只是想显示一条消息,我可以将它放在
docatations()
方法的末尾,一切都会正常工作

我知道我一定是在线程处理上做错了,但我找不到它。有什么想法吗

PS:一个想法:实际上
docations()
方法有自己的线程。因此,它“在线程内的SwingWorker中”运行。i首先使用
。join()工作正常。但是在调用
docatations()
方法之后,第一个
线程被认为已经完成,这就是为什么代码继续执行第二个
线程,而不知道
docatations()
线程仍在做一些事情。

试试看

a.doCaculations();
a.join();
编辑:
由于您使用的是SwingWorker,我之前的回答不正确,但是,正如您在评论中所说的,您已经扩展了线程,以下内容应该适用于您:

Thread a = new Calculations();
a.start();
a.join();
不要忘记,您必须在计算类中重写
run
方法,如:

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

编辑:
由于您使用的是SwingWorker,我之前的回答不正确,但是,正如您在评论中所说的,您已经扩展了线程,以下内容应该适用于您:

Thread a = new Calculations();
a.start();
a.join();
不要忘记,您必须在计算类中重写
run
方法,如:

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

在java中,您可以使用swingworker,并在done()方法中调用您的对话框


在android中,您可以使用AsyncTask调用新线程,在OnPostExecute方法中,调用ShowMessage dialog。

在java中,您可以使用swingworker,在done()方法中调用您的对话框


在android中,您可以使用AsyncTask调用新线程,在OnPostExecute方法中,调用ShowMessage对话框。

您的计算类必须扩展SwingWorker。您可以在
doInBackground()中进行计算

编辑:如果您想在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();
        }
    }
}

计算的每种方法中
都会像以前一样创建一个新的
SwingWorker
,并通过调用
SwingWorker.get()等待它完成

您的计算类必须扩展SwingWorker。您可以在
doInBackground()中进行计算

编辑:如果您想在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();
        }
    }
}
在每种
计算方法中
都创建一个新的
SwingWorker