Как использовать 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
параллельно.
Ответы
Ответ 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/