Поток JavaFX зависает при использовании ExecutorService - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь написать программу, которая использует API Imgur для загрузки изображений на основе имени учетной записи.

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 для выполнения всех сетевых запросов.

...