Подтвердить что ты не робот

Как использовать Callable с типом возврата void?

Я работаю над проектом, в котором у меня есть несколько интерфейсов и два класса реализации, которым необходимо реализовать эти два интерфейса.

Предположим, что мой первый интерфейс -

public Interface interfaceA {
    public void abc() throws Exception;
}

И его реализация -

public class TestA implements interfaceA {

// abc method
}

Я называю это так:

TestA testA = new TestA();
testA.abc();

Теперь мой второй интерфейс -

public Interface interfaceB {
    public void xyz() throws Exception;
}

И его реализация -

public class TestB implements interfaceB {

// xyz method   
}

Я называю это так:

TestB testB = new TestB();
testB.xyz();

Проблема: -

Теперь мой вопрос: есть ли способ, я могу выполнить эти два класса реализации параллельно? Я не хочу запускать его последовательно.

Значение, я хочу запустить параллельную реализацию TestA и TestB? Можно ли это сделать?

Я думал использовать Callable здесь, но не знаю, как использовать Callable с типом возврата void здесь -

В качестве примера можно использовать класс TestB:

public interface interfaceB {
    public void xyz() throws Exception;
}

public class TestB implements interfaceB, Callable<?>{

    @Override
    public void xyz() throws Exception
    {
        //do something

    }

    @Override
    public void call() throws Exception
    {
        xyz();
    }
}

Выше код дает ошибку компиляции.

UPDATE: -

Похоже, что многие люди предлагают использовать Runnable вместо вызываемого. Но не знаю, как использовать Runnable здесь, чтобы я мог выполнять TestA and TestB параллельно.

4b9b3361

Ответ 1

Вы можете использовать java.lang.Thread для параллельного выполнения. Однако в большинстве случаев проще использовать java.util.concurrent.ExecutorService. Последний предоставляет способ отправки Callable и возвращает Будущее, чтобы получить результат позже (или дождаться завершения).

Если testA.abc() и testB.xyz() должны выполняться параллельно, вы используете ExecutorService для выполнения первого в отдельном потоке, тогда как последний выполняется в исходном потоке. Затем вы ожидаете завершения первого для синхронизации.

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);

Future<Void> future = executor.submit(new Callable<Void>() {
    public Void call() throws Exception {
        testA.abc();
        return null;
    }
});
testB.xyz();
future.get(); // wait for completion of testA.abc()

Ответ 2

Зачем вам нужна пустота для запуска чего-то в Parallel? Например, если вам не требуется возвращаемое значение, вы можете просто вернуть null.

Чтобы сделать что-то параллельное, вам нужно использовать потоки/планирование. Я лично рекомендовал бы избегать Callables и вместо этого использовать Runnables (и hey, no return value).

Ответ 3

Более короткая версия:

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(() -> testA.abc());
testB.xyz();
future.get(); // wait for completion of testA.abc()

Следует отметить, что необходимость запускать что-то параллельно, ничего не возвращая, может быть признаком плохого паттерна :)

Кроме того, если вы находитесь в среде Spring, вы можете использовать: https://spring.io/guides/gs/async-method/