S
S
sanex33392016-01-12 21:13:44
Java
sanex3339, 2016-01-12 21:13:44

ExecutorService - how to get data from multiple Callable threads correctly?

There is a class that implements Callable and returns the results of calculations. The calculations themselves last about 2-3 seconds.
It is necessary to continuously endlessly receive the result from this class in 8 threads. The data returned by each thread is in no way dependent on each other. The received data is summarized with each other in the main thread of execution.
Now done like this:

public void run () {
        executorService = Executors.newFixedThreadPool(this.threadsCount); // 8 потоков
        threadsPool = new ArrayList<>();

        for (int i = 0; i < threadsCount; i++) {
            threadsPool.add(
                executorService.submit(
                    dataProvider.callback() // возвращает Callable
                )
            );
        }

        while (threadsPool.size() > 0) {
            startThread();
        }

        executorService.shutdown();
    }

private void startThread () {
        try {
            dataHandler.callback(
                threadsPool.get(0) // отправляем полученные данные на суммирование
            );
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }

        threadsPool.remove(0); // удаляем текущий поток
        threadsPool.add(
            this.executorService.submit(
               dataProvider.callback() // добавляем новый заместо старого
            )
        );
    }

Are there better ways to do the same? And how can I speed up the process?
UPD:
I just made a couple of tests, I have an i7 2600k, with threadsCount = 6 30 iterations of calculations (30 results from threads) were performed in 1:23 seconds, with threadsCount = 4 - 1:16, with threadsCount = 8 - about 1:50 .
Although, in theory, the more threads, the faster the calculations should be.
Those. obviously something is wrong with the implementation of the thread pool.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
sanex3339, 2016-01-13
@sanex3339

Found a solution using CompletitionService.

executorService = Executors.newFixedThreadPool(threadsCount);
        completionService = new ExecutorCompletionService<>(executorService);

        for (int i = 0; i < threadsCount; i++) {
            completionService.submit(
                renderDataProvider.callback()
            );
        }

        while (true) {
            try {
                renderDataHandler.callback(
                    completionService.take()
                );
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }

            completionService.submit(
                renderDataProvider.callback()
            );
        }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question