【问题标题】:How to use Callable with void return type?如何使用具有 void 返回类型的 Callable?
【发布时间】:2014-05-12 19:09:39
【问题描述】:

我正在从事一个项目,其中我有多个接口和两个需要实现这两个接口的实现类。

假设我的第一个接口是 -

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();

问题陈述:-

现在我的问题是 - 有什么办法可以并行执行这两个实现类吗?我不想按顺序运行它。

意思是,我想并行运行TestATestB 实现?这可以吗?

我想在这里使用 Callable 但不确定如何在这里使用带有 void 返回类型的 Callable -

我们以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();
    }
}

上面的代码给出了编译错误..

更新:-

看起来很多人建议使用 Runnable 而不是 callable。但不知道如何在这里使用 Runnable 以便我可以并行执行TestA and TestB

【问题讨论】:

  • 您可以使用Void 代替void 并返回null 作为虚拟返回值。
  • 您可能希望使用Runnable 而不是Callable
  • @ajb:如果可能的话,您能否提供一个示例如何在此处使用 Runnable,以便我可以并行执行 TestA 和 TestB。
  • @ajb Runnable 在某些情况下可能不起作用。例如:ExecutorService#invokeAll 采用 Callable 的集合,但 采用 Runnable 的集合。

标签: java multithreading callable


【解决方案1】:

您可以使用 java.lang.Thread 进行并行执行。但是,在大多数情况下,使用 java.util.concurrent.ExecutorService 会更容易。后者提供了提交一个Callable的方法,并返回一个Future以便稍后得到结果(或者等待完成)。

如果 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()

【讨论】:

  • 非常好!我不知道我们在模板参数中使用了一个 Void 类...
【解决方案2】:

为什么你需要一个 void 来并行运行某些东西?其一,如果不需要返回值,直接返回null即可。

要使某些东西并行化,您需要使用线程/调度。我个人建议避免使用 Callables,而是使用 Runnables(嘿,没有返回值)。

【讨论】:

  • 感谢您的建议。那你能给我举个例子,我如何使用 Runnable 而不是 callable 并行执行 TestA 和 TestB 吗?
  • ExecutorService 可能是并行执行两个任务的最佳方法。它还支持Runnable。但是,Callable 的优势在于还支持任意异常。
  • 流氓 - 在这种情况下使用可调用对象有什么问题?
  • @IcedD​​ante 由于它们的异常处理,我一直避免使用它们,这导致我不得不调试东西只是为了找出可调用的异常正在引发而不是打印/抛出上下文
【解决方案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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-18
    • 2020-10-20
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    相关资源
    最近更新 更多