#java #garbage-collection #threadpoolexecutor
#java #сбор мусора #threadpoolexecutor
Вопрос:
Запустив следующий код, вы можете получить java.util.concurrent.RejectedExecutionException
исключение.
/**
* -Xmx20m -Xms20m
*
*/
public class SingleThreadPoolTest {
public static void main(String[] args) {
for (int i = 0; i < 20000; i ) {
newSingleThreadPool();
}
}
private static void newSingleThreadPool() {
// create a SingleThreadExecutor then submit a task to it
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
byte[] bytes = new byte[1024 * 1024 * 4];
System.out.println(Thread.currentThread().getName());
}
});
}
}
Проблема здесь в том, что SingleThreadExecutor
объект может быть собран с помощью GC, который выполнит его finalize
, так что пул потоков будет отключен до submit
завершения выполнения его метода экземпляра.
Это казалось нелогичным, это привело бы к ошибкам. Мой вопрос в том, как это могло произойти? Это нормальное поведение GC? И есть ли какой-либо другой язык, на котором GC имеет проблему?
Вот ошибка, о которой сообщается системе ошибок jdk: Executors.newSingleThreadExecutor().submit(runnable) вызывает исключение RejectedExecutionException
Комментарии:
1. Обсуждение в отчете об ошибке не дает ответов на ваши вопросы? Если нет, то что конкретно?
2. @Kayaman Обсуждение сосредоточено на том, как возникает эта конкретная проблема, почему она была разработана таким образом; похоже, что эта ранняя сборка происходит только тогда, когда мы используем поток. Интересно, является ли это общей проблемой языков, в которых есть GC, и есть ли какое-либо возможное решение, позволяющее избежать таких проблем.
3. Вы понимаете, что это особый случай? Они даже упоминают, что добавляемый финализатор является почти «одолжением», потому что люди не закрывали своих исполнителей должным образом. Это также показывает некоторые опасности завершения. Также обсуждаются решения или обходные пути.
4. Но, согласно JLS, JVM разрешено собирать объект, поэтому вопрос заключается в том, следует ли изменять JLS или программисты должны нести ответственность за написание правильного кода. Спорно, какая из них является более сложной задачей 😉