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