使用ExecutorService时JavaFX线程挂起

时间:2018-11-21 15:28:49

标签: java multithreading javafx executorservice

我正在尝试编写一个使用Imgur的API根据帐户名下载图像的程序。

private volatile int threadCount;
private volatile double totalFileSize;
private volatile List<String> albums = new ArrayList<>();
private volatile Map<JSONObject, String> images = new HashMap<>();

private final ExecutorService executorService = Executors.newFixedThreadPool(100, (Runnable r) -> {
        Thread t = Executors.defaultThreadFactory().newThread(r);
        t.setDaemon(true);
        return t;
    });

private void downloadAlbums(List<String> albums) {
    threadCount = 0;
    albums.forEach((albumHash) -> {
        if (hasRemainingRequests()) {
            incThreadCount();
            executorService.execute(() -> {
                try {
                    String responseString;
                    String dirTitle;
                    String albumUrl = URL_ALBUM + albumHash;
                    String query = String.format("client_id=%s", URLEncoder.encode(CLIENT_ID, CHARSET));
                    URLConnection connection = new URL(albumUrl + "?" + query).openConnection();
                    connection.setRequestProperty("Accept-Charset", CHARSET);
                    InputStream response = connection.getInputStream();

                    try (Scanner scanner = new Scanner(response)) {
                        responseString = scanner.useDelimiter("\\A").next();
                        JSONObject obj = new JSONObject(responseString).getJSONObject("data");
                        dirTitle = obj.getString("title");
                        String temp = "";

                        // Get save path from a TextField somewhere else on the GUI
                        ObservableList<Node> nodes = primaryStage.getScene().getRoot().getChildrenUnmodifiable();
                        for (Node node : nodes) {
                            if (node instanceof VBox) {
                                ObservableList<Node> vNodes = ((VBox) node).getChildrenUnmodifiable();
                                for (Node vNode : vNodes) {
                                    if (vNode instanceof DestinationBrowser) {
                                        temp = ((DestinationBrowser) vNode).getDestination().trim();
                                    }
                                }
                            }
                        }
                        final String path = temp + "\\" + formatPath(accountName) + "\\" + formatPath(dirTitle);
                        JSONArray arr = obj.getJSONArray("images");
                        arr.forEach((jsonObject) -> {
                            totalFileSize += ((JSONObject) jsonObject).getDouble("size");
                            images.put((JSONObject) jsonObject, path);
                        });
                    }

                } catch (IOException ex) {
                    //
                } catch (Exception ex) {
                    //
                } finally {
                    decThreadCount();
                    if (threadCount == 0) {
                        Platform.runLater(() -> {

                            DecimalFormat df = new DecimalFormat("#.#");
                            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);//                      714833218
                            alert.setHeaderText("Found " + images.size() + " images (" + (totalFileSize < 1000000000 ? df.format(totalFileSize / 1000000) + " MB)" : df.format(totalFileSize / 1000000000) + " GB)"));
                            alert.setContentText("Proceed with download and save images?");
                            Optional<ButtonType> alertResponse = alert.showAndWait();

                            if (alertResponse.get() == ButtonType.OK) {
                                progressBar.setTotalWork(images.size());
                                executorService.execute(() -> {
                                    for (JSONObject obj : images.keySet()) {
                                        (new File(images.get(obj))).mkdirs();
                                        downloadImage(obj, images.get(obj));
                                    }
                                });
                            }
                        });
                    }
                }
            });
        }
    });
}

albums是将GET请求发送到Imgur以便接收该专辑的图像所需的代码列表。然后,将返回的数据用于下载图像本身的另一种方法中。 现在,所有这些工作正常,但是当程序发出所有GET请求时,JavaFX线程将挂起(GUI变得无响应)。并且,在执行完所有GET请求之后,JavaFX线程停止挂起,并且alert显示正确的信息。 我只是不明白为什么当我没有(我相信我没有)阻止它的线程并且我正在使用ExecutorService来执行所有网络请求时,GUI变得无响应。

0 个答案:

没有答案