void (final Path directory, final Predicate<Path> directoryConsumer, final Consumer<Path> fileConsumer) { if (!directoryConsumer.test(directory)) { throw new AssertionError("Code bug: " + directory + " must be a directory"); } final List<RecursiveAction> subDirectoryActions = new ArrayList<>(); final List<Path> plainFilesPaths = new ArrayList<>(); try (final DirectoryStream<Path> paths = Files.newDirectoryStream(directory)) { for (Path child : paths) { if (Files.isDirectory(child, NOFOLLOW_LINKS)) { final RecursiveAction walkSubdir = new RecursiveAction() { @Override protected void compute() { scanDirectoryWithDirectoryStreamFJP_NOFOLLOW_LINKS(child, directoryConsumer, fileConsumer); } }; walkSubdir.fork(); subDirectoryActions.add(walkSubdir); } else { plainFilesPaths.add(child); } } } catch (IOException e) { ExceptionUtil.rethrow(e); } for (Path filePath : plainFilesPaths) { fileConsumer.accept(filePath); } for (RecursiveAction action : subDirectoryActions) { action.join(); } }