У нашего Java приложения возникает проблема, когда оно блокируется на неопределенный срок, когда оно пытается выполнить запись в файл журнала, расположенный на общем ресурсе NFS, а общий ресурс NFS недоступен.
Мне было интересно, можем ли мы решить эта проблема, когда Future выполняет операцию записи с таймаутом. Вот небольшая тестовая программа, которую я написал:
public class write_with_future {
public static void main(String[] args) {
int iteration=0;
while (true) {
System.out.println("iteration " + ++iteration);
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new Runnable() {
public void run() {
try {
Category fileLogCategory = Category.getInstance("name");
FileAppender fileAppender = new FileAppender(new SimpleLayout(), "/usr/local/app/log/write_with_future.log");
fileLogCategory.addAppender(fileAppender);
fileLogCategory.log(Priority.INFO, System.currentTimeMillis());
fileLogCategory.removeAppender(fileAppender);
fileAppender.close();
}
catch (IOException e) {
System.out.println("IOException: " + e);
}
}
});
try {
future.get(100L, TimeUnit.MILLISECONDS);
}
catch (InterruptedException ie) {
System.out.println("Current thread interrupted while waiting for task to complete: " + ie);
}
catch (ExecutionException ee) {
System.out.println("Exception from task: " + ee);
}
catch (TimeoutException te) {
System.out.println("Task timed out: " + te);
}
finally {
future.cancel(true);
}
executorService.shutdownNow();
}
}
}
Когда я запустил эту программу с максимальным размером кучи 1 МБ, а общий ресурс NFS был запущен, эта программа смогла выполнить более 1 миллиона итераций, прежде чем Я остановил его.
Но когда я запустил программу с максимальным размером кучи 1 МБ, а общий ресурс NFS был недоступен, программа выполнила 584 итерации, каждый раз получая исключение TimeoutException, а затем с ошибкой java.lang.OutOfMemoryError
ошибка. Поэтому я думаю, что даже при вызове future.cancel(true)
и executorService.shutdownNow()
потоки исполнителя блокируются при записи и не отвечают на прерывания, и программе в конечном итоге не хватает памяти.
Есть ли любой способ очистить потоки исполнителя, которые заблокированы?