Фон «утечка ресурсов: поток никогда не закрывается» - PullRequest
3 голосов
/ 17 апреля 2020

Учитывая функцию Java, которая использует поток:

List<String> function(List<String> input) {
    Stream<String> a = input.parallelStream();
    Stream<String> b = a.map(c -> c.toString());
    return b.collect(Collectors.toList());
}

Теперь я хочу контролировать, выполняется ли отображение параметром. Eclipse / компилятор выдает мне предупреждение: Утечка ресурсов: 'a' никогда не закрывается

List<String> function(List<String> input, boolean doMap) {
    Stream<String> a = input.parallelStream(); // Resource leak: 'a' is never closed
    Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
    return b.collect(Collectors.toList());
}

Я могу обойти это с помощью оператора try-with-resources:

List<String> function(List<String> input, boolean doMap) {
    try (Stream<String> a = input.parallelStream()) {
        Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
        return b.collect(Collectors.toList());
    }
}

Мой вопрос: почему вообще могут быть утечки ресурсов, когда я работаю с потоками вместо циклов for? Почему происходит утечка ресурсов, если я только добавляю шаг сопоставления? (Почему в первой версии функции нет утечки ресурсов?) «Опасно» ли составлять потоки обработки условно? Чего мне не хватает?

1 Ответ

0 голосов
/ 04 мая 2020

Я суммирую @ Nikolas и снова отвечу другими словами: в Java нет проблемы, но «проблема» (если вы вообще хотите это так называть) - это переменная. Если переменная объявлена ​​для типа, который реализует AutoCloseableStream делает), Eclipse, очевидно, сообщает здесь предупреждение о том, что она не закрывается, если она не находит вызов close().

Так как эта ошибка связана с Eclipse, вполне вероятно, что другие инструменты проверки не прервутся на этом и не нуждаются в «исправлении» для прохождения таких проверок.

Насколько я понимаю, это показывает основные c проблема Java, а именно в том, что он не освобождает объект от переменной, как только он больше не нужен, но в некоторой случайной точке. С ресурсами это не получается. Поэтому ресурсы должны отслеживаться разработчиком вручную, где их закрывать, и вручную закрывать. Среда выполнения Java (гипотетически) должна была бы реализовать такой подход, как std::auto_ptr в C ++, тогда в этом не было бы необходимости, и, если была удалена последняя ссылка на ресурс, это можно было бы закрыть. Но это не то, что java "думает".

...