JavaFX.Join()关键字导致应用程序冻结一段时间
我有几行跳线需要在运行JavaFX.Join()关键字导致应用程序冻结一段时间,java,multithreading,javafx,Java,Multithreading,Javafx,我有几行跳线需要在运行线程时执行。因此,我在稍后要执行的跳线之前使用了thread.join()关键字 当我使用join()关键字运行程序时,我的应用程序界面会被卡住,直到线程执行完成。我如何克服这个问题 实际上,我的程序所做的是,一旦我按下按钮,它将执行方法调用Pass_data_from_java_to_report()在运行时,会出现一个单独的视图或阶段,通知用户程序仍在运行。一旦上述方法完成执行,将通过调用Stage.close()关闭等待的Stage。这些操作工作正常,但是使用join
线程时执行。因此,我在稍后要执行的跳线之前使用了thread.join()
关键字
当我使用join()
关键字运行程序时,我的应用程序界面会被卡住,直到线程执行完成。我如何克服这个问题
实际上,我的程序所做的是,一旦我按下按钮,它将执行方法调用Pass_data_from_java_to_report()代码>在运行时,会出现一个单独的视图或阶段
,通知用户程序仍在运行。一旦上述方法完成执行,将通过调用Stage.close()
关闭等待的Stage
。这些操作工作正常,但是使用join关键字进行冻结
这是我的第一个方法。
if(event.getSource() == btnAdd){
Stage stage = Waiting(); // Returns Waiting Message
Task <Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
Pass_data_from_java_to_report(); // My Method
return null;
}
};
// Displaying Waiting Message
task.setOnRunning(eve -> {
stage.show();
});
// Closing Waiting Message
task.setOnSucceeded(e -> {
stage.close();
});
// Thread for executing task
Thread t1 = new Thread(() -> {
task.run();
});
t1.start();
t1.join(); // if i remove this buddy, there is no freezing
// below from here i want to execute upon thread completion
System.out.println("Finish ");
}
以下是方法
public void Pass_query_to_report(){
try {
// Since method is not time consuming,
// i added 3 sec sleep before the Execution
Thread.sleep(3000);
/*
Some cord
*/
} catch (Exception e) {
e.printStackTrace();
}
}
我怎样才能克服这个问题
哪种方法最适合使用。。?是方法一还是方法二
关闭在另一个线程中启动的阶段安全吗,就像我这样做的。。?它会自动关闭它所属的线程吗
(注意-我也尝试过使用CountDownLatch
,但运气不好)Thread.join()
会阻止当前线程,直到指定的线程完成。由于您是在FX应用程序线程上调用它的,FX应用程序线程负责呈现UI和处理用户事件,因此它会阻止该线程,使UI无响应
只需将任务完成后需要执行的代码移动到onSucceeded
处理程序:
if(event.getSource() == btnAdd){
Stage stage = Waiting(); // Returns Waiting Message
Task <Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
Pass_data_from_java_to_report(); // My Method
return null;
}
};
// Displaying Waiting Message
task.setOnRunning(eve -> {
stage.show();
});
// Closing Waiting Message
task.setOnSucceeded(e -> {
stage.close();
// below from here i want to execute upon thread completion
System.out.println("Finish ");
});
// Thread for executing task
Thread t1 = new Thread(task);
t1.start();
}
if(event.getSource()==btnAdd){
Stage=Waiting();//返回等待消息
任务=新任务(){
@凌驾
受保护的Void调用()引发异常{
将_数据_从_java_传递到_report();//我的方法
返回null;
}
};
//显示等待消息
task.setOnRunning(eve->{
stage.show();
});
//正在关闭等待消息
task.setonsucceed(e->{
stage.close();
//下面我想在线程完成后执行
系统输出打印(“完成”);
});
//用于执行任务的线程
线程t1=新线程(任务);
t1.start();
}
Thread.join()
阻止当前线程,直到指定的线程完成。由于您是在FX应用程序线程上调用它的,FX应用程序线程负责呈现UI和处理用户事件,因此它会阻止该线程,使UI无响应
只需将任务完成后需要执行的代码移动到onSucceeded
处理程序:
if(event.getSource() == btnAdd){
Stage stage = Waiting(); // Returns Waiting Message
Task <Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
Pass_data_from_java_to_report(); // My Method
return null;
}
};
// Displaying Waiting Message
task.setOnRunning(eve -> {
stage.show();
});
// Closing Waiting Message
task.setOnSucceeded(e -> {
stage.close();
// below from here i want to execute upon thread completion
System.out.println("Finish ");
});
// Thread for executing task
Thread t1 = new Thread(task);
t1.start();
}
if(event.getSource()==btnAdd){
Stage=Waiting();//返回等待消息
任务=新任务(){
@凌驾
受保护的Void调用()引发异常{
将_数据_从_java_传递到_report();//我的方法
返回null;
}
};
//显示等待消息
task.setOnRunning(eve->{
stage.show();
});
//正在关闭等待消息
task.setonsucceed(e->{
stage.close();
//下面我想在线程完成后执行
系统输出打印(“完成”);
});
//用于执行任务的线程
线程t1=新线程(任务);
t1.start();
}
您只能关闭FX应用程序线程中的阶段(这就是您正在做的:在该线程上执行onSucceeded
处理程序和其他类似处理程序)。无需在标题中添加“已解决”:接受答案表明问题已得到回答。尽管禁止发表感谢评论,我要说谢谢你抽出时间……)您只能关闭FX应用程序线程中的阶段(这就是您正在做的:在该线程上执行onSucceeded
处理程序和其他类似处理程序)。无需在标题中添加“已解决”:接受答案表明问题已得到回答。尽管禁止使用感谢评论,我要说谢谢你抽出时间……)增加了对答案的解释。(简而言之,它完全按照预期工作。)因此,每当我使用GUI时,我应该像第一种方法一样使用任务
,而对于非GUI,我应该使用线程
作为第二种方法。嗯,不。两条规则是:1。修改UI的代码必须在FX应用程序线程上执行。2.需要较长时间执行的代码或块应该在后台线程上运行。您可以使用Task
s或plainRunnable
s,以最方便的为准:Task
提供了在FX应用程序线程上执行代码的有用方法(例如onSucceeded
等)。在第二种方法中,第一个线程无论如何都是完全冗余的(您创建一个后台线程,其唯一目的是安排代码在FX应用程序线程上运行:您也可以直接调用stage.show()
)。为答案添加了解释。(简而言之,它完全按照预期工作。)因此,每当我使用GUI时,我应该像第一种方法一样使用任务
,而对于非GUI,我应该使用线程
作为第二种方法。嗯,不。两条规则是:1.修改UI的代码必须在FX应用程序线程上执行。2.执行时间长或阻塞的代码应该在后台运行d线程。您可以使用Task
s或普通Runnable
s,以最方便的为准:Task
提供了在FX应用程序线程上执行代码的有用方法(例如onSucceeded
等)。在第二种方法中,第一个线程无论如何都是完全冗余的(创建一个后台线程,其唯一目的是安排代码在FX应用程序线程上运行: