Как сделать медленный цикл Java for более быстрым с многопоточностью? - PullRequest
0 голосов
/ 06 мая 2018

Скажем, у меня очень медленный и большой цикл for.

Как мне разделить это на несколько потоков, чтобы он работал быстрее?

for (int a = 0; a < 30000000; a++) {
    for (int b = 0; b < 30000000; b++) {
        for (int c = 0; c < 30000000; c++) {
           slowMethod();
        }
    }
}

1 Ответ

0 голосов
/ 06 мая 2018

Это немного шире, но использование ExecutorService с фиксированным номером потока сделает его быстрее, когда номер процессора больше 1 и slowMethod не зависит. Если slowMethod требует интенсивного ввода-вывода, вы можете увеличить номер потока, чтобы повысить производительность.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(
                   Runtime.getRuntime().availableProcessors() + 1);

        for (int a = 0; a < 30000000; a++) {
            for (int b = 0; b < 30000000; b++) {
                for (int c = 0; c < 30000000; c++) {
                    final int a_copy = a;
                    final int b_copy = b;
                    final int c_copy = c;
                    service.execute(() -> {
                            slowMethod(a_copy, b_copy, c_copy);
                    });
                }
            }
        }
    }

    public static void slowMethod(int a, int b, int c) {

    }
}

Обновление

Как сказано в комментарии, это может привести к прерыванию задачи, поскольку емкость очереди составляет Integer.MAX_VALUE. Вы можете позволить основному потоку выполнить slowMethod, когда очередь заполнена. Для этого вам необходимо создать пул вручную:

BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
int threads = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(threads, threads,
        0, TimeUnit.MILLISECONDS,
        queue, Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.CallerRunsPolicy());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...