Многопоточность лучшие практики в Java

Я новичок в программировании на Java. У меня есть дело, где я должен выполнить 2 запроса параллельно. Структура моего класса примерно такая:--3-->

class A {
    public Object func_1() {
        //executes db query1
    }

    public Object func_2() {
        //executes db query1
    }
}

теперь у меня есть добавить другую функцию func_3 в том же классе, который вызывает эти 2 функции, но также гарантирует, что они выполняются параллельно. Для этого я использую callables и futures. Правильно ли это использовать? Я сохраняю эту переменную во временной переменной, а затем использую ее для вызова func_1 и func_2 из func_3 (который я не уверен, что это правильный подход). Или есть другой способ справиться с такими делами?

class A {
    public Object func_1() {
        //executes db query1
    }

    public Object func_2() {
        //executes db query1
    }

    public void func_3() {
        final A that = this;
        Callable call1 = new Callable() {
            @Override
            public Object call() {
               return that.func_1();
            }
        }

        Callable call2 = new Callable() {
            @Override
            public Object call() {
               return that.func_2();
            }
        }
        ArrayList<Callable<Object>> list = new ArrayList<Callable<Object>>();
        list.add(call1);
        list.add(call2);
        ExecutorService executor = Executors.newFixedThreadPool(2);
        ArrayList<Future<Object>> futureList = new ArrayList<Future<Object>>();
        futureList = (ArrayList<Future<Object>>) executor.invokeAll(list);
        //process result accordingly
    }
}

2 ответов


прежде всего, вам не нужно хранить это в другой локальной переменной: внешние функции будут доступны так же, как func_1() или func_2() и когда вы хотите сделать this внешнего класса вы просто используете A.this.

во-вторых, да, это обычный способ сделать это. Кроме того, если вы собираетесь часто вызывать func_3 - избегайте создания пула фиксированных потоков, вы должны просто передать его как params, так как создание потока довольно "дорого".


вся идея исполнителя (службы) заключается в использовании небольшого количества потоков для многих небольших задач. Здесь вы используете 2-threaded executor для 2 задач. Я бы либо создал глобально определенный исполнитель, либо просто породил 2 потока для 2 задач.