Совместно используемые данные Java с Runnable против Callable и локальных данных

Первый случай. Допустим, у вас есть много задач, которые все возвращают какой-то результат, на данный момент давайте просто назовем его "результатом", и все они должны храниться в массиве. Есть два варианта:

1) Создайте один массив в основном методе и используйте runnables с доступом к общему списку и синхронизированным методом добавления

2) Создайте один массив в основном методе и используйте callable для выполнения задачи, верните результат и позвольте основному методу добавить Result в свой список.

Есть ли какие-то различия в производительности между ними, поскольку для запуска требуется синхронный доступ, а для вызовов - нет?

Затем, во втором случае: давайте теперь скажем, что каждая задача генерирует "маленький" массив, скажем, менее 10 элементов на задачу. Это снова дает два варианта:

1) Один массив в main и runnables с доступом к общему списку, который добавляет элементы результата при генерировании.

2) Один arrayList в main и вызываемых> с каждым собственным локальным массивом, который хранит результаты до тех пор, пока задача не будет завершена, а затем в main addAll используется для добавления найденного результата.

Тот же вопрос, что и раньше, в чем разница в производительности?

Для ясности, производительность как с точки зрения скорости (некоторые проблемы с синхронизацией и т. Д.), Так и с точки зрения памяти (используют ли вызываемые объекты гораздо больше памяти из-за локального небольшого массива или это мало, чтобы пренебречь)?

1 ответ

For the First Case: 
  1. Вариант первый: если мы используем задачи Runnable, то мы не можем получить что-либо возвращаемое из метода run(). Поэтому я думаю, что этот вариант не будет соответствовать вашим требованиям.

  2. Вариант второй: Callable Согласно моему пониманию вашего требования, Callable является хорошим кандидатом. Но есть небольшое изменение: мы создадим список Future и для каждой задачи Callable(которую мы представим исполнителям) добавим в этот список результат Future этого Callable(подробности см. Ниже). Тогда всякий раз, когда нам нужен результат какой-либо задачи, мы можем получить результат из соответствующего будущего.

class MainTaskExecutor {

private static ExecutorService  exe = Executors.newCachedThreadPool();
private static List<Future<Result>> futureResults = new ArrayList<>();

public static void main(String[] args) throws ExecutionException, InterruptedException {
    Callable<Result> dummyTask = ()-> {
        System.out.println("Task is executed");
        Result dummyResult = new Result();
        return dummyResult;
    };

    //Submit a task
    submitTask(dummyTask);

    //Getting result of "0" index
    System.out.println(futureResults.get(0).get());
}

private static void submitTask(Callable<Result> task) {
    futureResults.add(exe.submit(task));
}

private static Result getResult(int taskNumber) throws ExecutionException, InterruptedException {
    return futureResults.get(taskNumber).get();
}

}

class Result {
    // data to be added
}
Другие вопросы по тегам