How to design my JavaFX Service / Tasks for calculating 4 checksums of a file?

Solution 1:

Make your checksum calculator a Task, instead of a Service:

public class ChecksumCalculatorTask extends Task<String> {

    private static final Logger logger = LogManager.getLogger();

    private final KnkFile knkFile;
    private final Algorithm algorithm;

    public ChecksumCalculatorService(KnkFile f, Algorithm algorithm) {
        this.knkFile = f;
        this.algorithm = algorithm;
    }

    public KnkFile getKnkFile() {
        return knkFile;
    }

    private String getChecksumOfFile() throws IOException, NoSuchAlgorithmException {

        // ...

    }

    @Override
    protected String call() throws Exception {
        return getChecksumOfFile();
    }
}

Create an executor:

private ExecutorService exec = Executors.newCachedTheadPool() ;

Now you can submit the tasks to the executor:

public static void handleNewFiles(List<File> files) {

    List<ChecksumCalculatorTask> tasks = new ArrayList<>();

    for (java.io.File file : files) {
        KnkFile knkFile = new KnkFile(file.getAbsolutePath());

        ChecksumCalculatorTask sha256task = new ChecksumCalculatorTask(knkFile, Algorithm.SHA_256);
        tasks.add(sha256Task);
        sha256task.setOnSucceeded(event -> {
            logger.debug(knkFile);
        });
        exec.execute(task);
    }

    
    // Create a `Task` that waits until they're finished and processes tham all:

    Task<Void> processCompletedTasks = new Task<>() {
        @Override
        protected Void call() throws Exception {
            // block until tasks complete:
            for (Future<?> f : tasks) {
                f.get();
            }
            // process completed tasks:
            for (ChecksumCalculatorTask task : tasks) {
                KnkFile file = task.getKnkFile() ;
                String checksum = task.getValue();
                // ... whatever you need here, note this is on background thread
            }
        }
    };
    exec.submit(processCompletedTasks);
}