【问题标题】:Will Java asyncronously call these methods automatically?Java 会自动异步调用这些方法吗?
【发布时间】:2014-01-31 06:52:36
【问题描述】:

假设我这样调用一个方法:

myBigMethod(
  getMethodParam1(arg1, arg2),
  getMethodParam2(arg2, arg3),
  getMethodParam3(arg3, arg4)
);

Java 是否会异步调用 getMethodParam1、getMethodParam2 和 getMethodParam3?

【问题讨论】:

标签: java asynchronous concurrency


【解决方案1】:

如果您不告诉它这样做,Java 将永远不会异步执行任何操作。

假设有一个像myBigMethod(a, b, c) 这样的方法,它将首先评估每个参数,然后才能将结果传递给该方法。从左到右。

所以你的例子相当于:

a = getMethodParam1(arg1, arg2);
b = getMethodParam2(arg2, arg3);
c = getMethodParam2(arg3, arg4);
myBigMethod(a, b, c);

【讨论】:

    【解决方案2】:

    不,JVM会一一调用getMethodParam的方法。如果你想并行调用这些方法,你应该自己做

    【讨论】:

      【解决方案3】:

      如果您暗示的是 Haskell 的非严格求值语义,那么请放心,Java 与任何其他主要编程语言一样,具有严格的语义,并且参数仅按值传递,这意味着必须首先计算值.

      如果您的问题可能是关于 Java 是否保证参数求值顺序,那么答案是肯定的,表达式将始终从左到右求值。

      【讨论】:

        【解决方案4】:

        Java 将在调用方法之前评估参数。因此,在您的情况下,将在调用 myBigMethod 之前评估 getMethodParam1/2/3 。

        【讨论】:

          【解决方案5】:

          首先,您可以简单地通过一个测试和一个大的 for 循环来检查它。甚至调试,你会看到方法被一一调用。 想一想,如果 JVM 自己做出这样的决定,那可能会非常危险。

          【讨论】:

            【解决方案6】:

            如果希望异步运行一组方法调用或代码块,AsynHelper 库包含一个有用的帮助方法 AsyncTask.submitTasks,如下面的 sn-p。 p>

            AsyncTask.submitTasks(
                () -> getMethodParam1(arg1, arg2),
                () -> getMethodParam2(arg2, arg3)
                () -> getMethodParam3(arg3, arg4),
                () -> {
                         //Some other code to run asynchronously
                      }
                );
            

            如果希望等到所有异步代码运行完毕,可以使用 AsyncTask.submitTasksAndWait 变量。

            此外,如果希望从每个异步方法调用或代码块中获取返回值,则可以使用 AsyncSupplier.submitSuppliers 以便可以通过以下方式获得结果方法返回的结果供应商数组。以下是示例 sn-p:

            Supplier<Object>[] resultSuppliers = 
               AsyncSupplier.submitSuppliers(
                 () -> getMethodParam1(arg1, arg2),
                 () -> getMethodParam2(arg3, arg4),
                 () -> getMethodParam3(arg5, arg6)
               );
            
            Object a = resultSuppliers[0].get();
            Object b = resultSuppliers[1].get();
            Object c = resultSuppliers[2].get();
            

            然后可以根据您的用例将这些结果传递给 myBigMethod,如下所示

            myBigMethod(a,b,c);
            

            如果每个方法的返回类型不同,请使用下面的sn-p。

            Supplier<String> aResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam1(arg1, arg2));
            Supplier<Integer> bResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam2(arg3, arg4));
            Supplier<Object> cResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam3(arg5, arg6));
            
            myBigMethod(aResultSupplier.get(), bResultSupplier.get(), cResultSupplier.get());
            

            异步方法调用/代码块的结果也可以在同一线程或不同线程的不同代码点获得,如下面的sn-p。

            AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam1(arg1, arg2), "a");
            AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam2(arg3, arg4), "b");
            AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam3(arg5, arg6), "c");
            
            
            //Following can be in the same thread or a different thread
            Optional<String> aResult = AsyncSupplier.waitAndGetFromSupplier(String.class, "a");
            Optional<Integer> bResult = AsyncSupplier.waitAndGetFromSupplier(Integer.class, "b");
            Optional<Object> cResult = AsyncSupplier.waitAndGetFromSupplier(Object.class, "c");
            
             myBigMethod(aResult.get(),bResult.get(),cResult.get());
            

            【讨论】:

              猜你喜欢
              • 2011-04-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-04-26
              • 2021-01-18
              • 2010-12-22
              • 1970-01-01
              相关资源
              最近更新 更多