Java 任务悬而未决

Java 任务悬而未决,java,multithreading,intellij-idea,javafx,Java,Multithreading,Intellij Idea,Javafx,当我通过IntelliJ(最新版本)运行应用程序时,我的最后一个任务将永远挂起。 实际上,我尝试过调试,它挂在fetchRegisterCourseList()上。 我可以看到它的挂起,因为我有一个进度指示器,而特定的数据从未被获取。 另一方面,当我将我的应用程序打包到一个jar中并正常执行时,它不会挂起,一切正常 这是IntelliJ还是与代码相关的bug 授权控制器: ... // previous tasks Task<List<Course&

当我通过IntelliJ(最新版本)运行应用程序时,我的最后一个任务将永远挂起。 实际上,我尝试过调试,它挂在fetchRegisterCourseList()上。 我可以看到它的挂起,因为我有一个进度指示器,而特定的数据从未被获取。 另一方面,当我将我的应用程序打包到一个jar中并正常执行时,它不会挂起,一切正常

这是IntelliJ还是与代码相关的bug

授权控制器:

        ... // previous tasks

        Task<List<Course>> parseGradesTask = new Task<List<Course>>() {
            @Override
            public List<Course> call() {
                return studentParser.parseStudentGrades();
            }
        };

        Task<HashMap<String, String>> parseRegTask = new Task<HashMap<String, String>>() {
            @Override
            public HashMap<String, String> call() {
                return studentParser.parseStudentRegistration();
            }
        };

        parseGradesTask.setOnSucceeded(e -> {
            serializeService.serializeCourses(parseGradesTask.getValue());
            progressIndicator.setProgress(0.6);
        });

        parseRegTask.setOnSucceeded(e -> {
            // it is hanging at this line:
            List<Course> regList = serializeService.fetchRegisterCourseList(parseGradesTask.getValue(), parseRegTask.getValue());
            serializeService.serializeRegister(regList);
            updateMainComponents();
        });

        ExecutorService es = Executors.newSingleThreadExecutor();
        es.submit(parseInfoTask);
        es.submit(parseGradesTask);
        es.submit(parseStatsTask);
        es.submit(parseRegTask);
        es.shutdown();

private void updateMainComponents() {
    MainController.getInstance().updateAllViewComponents();

    if (preferenceService.getPreferences().getPrefSyncEnabled()) {
        SyncScheduler.getInstance().stopScheduler();
        SyncScheduler.getInstance().startSyncScheduler(preferenceService.getPreferences().getPrefSyncTime());
    }
    dialogStage.close(); //close this window
}
..//以前的任务
Task parseGradesTask=新任务(){
@凌驾
公共列表调用(){
return studentParser.parseStudentGrades();
}
};
Task parseRegTask=新任务(){
@凌驾
公共HashMap调用(){
return studentParser.parseStudentRegistration();
}
};
parseGradesTask.setOnSucceeded(e->{
serializeService.serializeCourses(parseGradesTask.getValue());
progressIndicator.setProgress(0.6);
});
parseRegTask.setOnSucceeded(e->{
//它悬挂在这条线上:
List regList=serializeService.fetchRegisterCourseList(parseGradesTask.getValue(),parseRegTask.getValue());
serializeService.serializeRegister(regList);
updateMainComponents();
});
ExecutorService es=Executors.newSingleThreadExecutor();
提交(parseInfoTask);
es.提交(parseGradesTask);
提交(parseStatsTask);
提交(parseRegTask);
es.shutdown();
私有void updateComponents(){
MainController.getInstance().updateAllViewComponents();
if(preferenceService.getPreferences().getPrefSyncEnabled()){
SyncScheduler.getInstance().stopScheduler();
SyncScheduler.getInstance().startSyncScheduler(preferenceService.getPreferences().getPrefSyncTime());
}
dialogStage.close();//关闭此窗口
}
序列化服务:

public List<Course> fetchRegisterCourseList(List<Course> courseList, HashMap<String, String> courseIdList) {
    List<Course> courseRegList = new ArrayList<>();

    Iterator it = courseIdList.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry) it.next();
        courseRegList.addAll(courseList.stream().filter(course ->
                course.getCourseId().equals(pair.getKey()) && course.getCourseTitle().equals(pair.getValue()))
                .collect(Collectors.toList()));
        it.remove(); // avoids a ConcurrentModificationException
    }
    return courseRegList;
}
public List fetchRegisterCourseList(List-courseList,HashMap-courseIdList){
List courseRegList=新建ArrayList();
迭代器it=courseIdList.entrySet().Iterator();
while(it.hasNext()){
Map.Entry对=(Map.Entry)it.next();
courseRegList.addAll(courseList.stream().filter(课程->
course.getCourseId().equals(pair.getKey())和&course.getCourseTile().equals(pair.getValue())
.collect(Collectors.toList());
it.remove();//避免ConcurrentModificationException
}
回程英语;
}

在JavaFX应用程序thead上调用已生成的
处理程序。此处不应执行长时间运行的操作。最好只在这里进行UI更新。
任务的结果可用于“发布”操作的结果。此值可以在
onSucceeded
处理程序中检索

在代码中,您正在
onSucceeded
处理程序中运行这些操作,该处理程序会阻止UI线程

以下示例显示如何正确使用
任务

@Override
public void start(Stage primaryStage) {
    TextArea textArea = new TextArea();
    Button button = new Button("Get Text");
    button.setOnAction(evt -> {
        button.setDisable(true);
        Task<String> task = new Task<String>() {

            @Override
            protected String call() throws Exception {
                // do long-running operations not modifying the UI
                // here
                StringBuilder sb = new StringBuilder();

                final int count = 10;

                for (int i = 0; i < count; i++) {
                    // update message & progress
                    // the messageProperty / progressProperty will be modified on
                    // the javafx application thread
                    updateProgress(i, count);
                    updateMessage("Loading part " + (i+1));

                    // simulate long-running operation
                    Thread.sleep(500);
                    sb.append('\n').append(i);
                }
                updateProgress(count, count);
                return sb.toString();
            }

        };

        // while loading, display the task message in the TextArea
        textArea.textProperty().bind(task.messageProperty());

        task.setOnSucceeded(succeededEvent -> {
            // only modifications of the UI here, no longrunning tasks
            textArea.textProperty().unbind();

            // use result of the task
            textArea.setText(task.getValue());

            button.setDisable(false);
        });

        // run task on different thread
        new Thread(task).start();
    });

    Scene scene = new Scene(new VBox(textArea, button));

    primaryStage.setScene(scene);
    primaryStage.show();
}
@覆盖
公共无效开始(阶段primaryStage){
TextArea TextArea=新建TextArea();
按钮按钮=新按钮(“获取文本”);
按钮设置操作(evt->{
按钮。设置禁用(true);
任务=新任务(){
@凌驾
受保护的字符串调用()引发异常{
//执行长时间运行的操作,但不修改UI
//这里
StringBuilder sb=新的StringBuilder();
最终整数计数=10;
for(int i=0;i{
//这里只修改UI,没有长时间运行的任务
textArea.textProperty().unbind();
//使用任务的结果
setText(task.getValue());
按钮。设置禁用(错误);
});
//在不同线程上运行任务
新线程(任务).start();
});
场景=新场景(新VBox(文本区域,按钮));
初级阶段。场景(场景);
primaryStage.show();
}

IDK所有这些语句都在做什么,但是昂贵的任务应该在
Task
s的
call
方法中完成。我没有看到您从
onSucceeded
处理程序中得到任何结果,这似乎更奇怪。从方法名称猜出
updateComponents()parseRegTask
,code>应该是在
onSucceeded
处理程序中执行的唯一内容。谢谢fabian。这似乎解决了我的问题。如果你愿意的话,你可以写下来作为结束这个问题的答案。虽然我很想知道为什么会发生这种情况(甚至是假设),但绝对不是IntelliJ bug。首先,最后,永远怀疑自己。是的,这就是我在这里发布的原因:)updateProgress和updateMessage()可以在call()中使用吗?从命名来看,我猜这些方法正在将属性更改为主JavaFX线程。@pror21我正在
调用
方法中使用这些方法,不是吗?这些确实可以从这个方法中调用,即使它运行在不同的线程上,请看,我不知道这些方法是任务cla的一部分