【发布时间】:2022-01-21 01:14:19
【问题描述】:
我正在开发一个 javafx 应用程序。由于我需要显示数据库中的一些数据,我开始了解在 Javafx 中使用Task。在看到 SO 上的solution 后,我尝试实现它。为了检查它是否有效,我只是打印了一个从我的数据库中获得的 HashTable 的团队列表。
当我第一次启动应用程序时,数据已成功获取并显示在我的控制台上,但是当我切换场景并尝试切换回主页(正在获取数据的位置)时,UI 完全冻结并显示它甚至不显示场景。
Home.java
public class Home implements Initializable {
private Executor executor;
private TeamsDAO teamsDAO;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
try{
teamsDAO = new TeamsDAO();
}catch (SQLException e){
e.printStackTrace();}
executor = Executors.newCachedThreadPool(runnable -> {
Thread th = new Thread(runnable);
th.setDaemon(true);
return th;
});
printTeams();
}
public void printTeams() {
Task<Hashtable<Integer, String>> displayTask = new Task<Hashtable<Integer, String>>() {
@Override
protected Hashtable<Integer, String> call() throws Exception {
return teamsDAO.getTeams();
}
};
displayTask.setOnFailed(e -> {
displayTask.getException().printStackTrace();
});
displayTask.setOnSucceeded(e -> {
cricProTitle.setText(displayTask.getValue().get(2));
});
executor.execute(displayTask);
}
}
我正在使用 HikariCP 作为 postgresql 的数据库连接池。
TeamsDAO.java
public class TeamsDAO {
private Connection conn;
public TeamsDAO() throws SQLException {
this.conn = DataSource.getConnection();
}
public Hashtable<Integer, String> getTeams() throws SQLException {
try (PreparedStatement pst = conn.prepareStatement("SELECT * FROM TEAMS")) {
ResultSet rs = pst.executeQuery();
Hashtable<Integer, String> teams = new Hashtable<>();
while (rs.next()) {
teams.put(rs.getInt("team_id"), rs.getString("name"));
}
return teams;
}
}
}
UI 冻结时不显示错误堆栈跟踪。我希望这些团队显示在主页上(在线程成功运行后)。请建议我哪里出错了?
【问题讨论】:
-
也许这会有所帮助? Concurrency in JavaFX
-
“......当我切换场景并尝试切换回主页(正在获取数据的地方)时,UI 完全冻结......”因为这似乎是导致问题的原因,我建议编辑您的问题并包含执行此操作的代码。
-
minimal reproducible example 请(硬编码线程中获取的数据,根据需要休眠)..
-
在调试器中运行它。单步执行代码。检查哪些线程被阻塞以及阻塞在哪里。
-
感谢您的建议,问题是由于切换场景一次又一次地重新加载,创建新线程并填满数据库连接池。