Java8中的lambda表达式是否会多线程执行?

5
在Java8中,引入了Lambda表达式。这个问题是关于并行Lambda何时被执行的。
在Java8之前,Callable类是执行多线程的一种方式。Callables可以与Executor类一起使用来执行。假设我正在使用一个固定线程池,使用3作为活动处理任务的数量。假设我有8个任务。固定线程池将启动前三个任务,并在完成一个任务后启动下一个任务,直到所有8个任务都完成。
如果我将我的任务实现为Java8 Lambda,会发生什么?所有8个任务会同时启动吗?还是顺序地?或者以任何聪明的方式?
特别地,它们是否在与调用者相同的线程中运行(不使用Exeuctor)?根据它们的性质,我猜测Lambda可以轻松地在另一个线程中执行。

3
Lambda表达式只是另一种编写相同代码的方式,它就像您要传递的Runnable一样可以运行。它不会影响它们执行的方式。也许我没有理解你的问题。 - Joffrey
1
你把Lambda表达式和“为你的樱桃添加更多汁液的东西”混淆了。实际上它们并不是这样的。它们是编译时或代码级别的改进,而不是字节码级别的改进。无论你的代码是否使用Lambda表达式,它都会编译成相同的字节码(几乎相同),并以相同的方式运行。所以如果你掌握了基础知识,就不用担心这个问题。 - Nazgul
可调用对象一旦被调用就立即执行。 - Peter Lawrey
在我的想法中,Lambda 函数本质上可以在自己的线程中执行。我知道,Lambda 函数在被调用时会立即执行。不过,它无论如何都会使用与调用者相同的线程(而不使用 Executor)?! - Markus Schulte
稍微更新了我的问题 - 这个问题不太涉及调用时间,而更多地涉及负载分配。 - Markus Schulte
显示剩余2条评论
1个回答

11
Runnable r = () -> System.out.println("hello");

等同于

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("hello")
    }
};

这并不会改变可运行代码的执行方式。如果您将可运行代码提交给线程池,则无论您使用lambda、匿名类还是顶级类创建可运行代码,线程池都会执行它。最终,您定义的只是一个Runnable实例,而这是唯一重要的事情。


那么 lambda 表达式不会在自己的线程中执行;除非我将其交给 Executor,否则它只会在当前线程中执行?我本来希望通过使用 lambda 表达式来获得多线程的好处。 - Markus Schulte
2
@MarcusSchultö,你可以把lambda看作是语法糖,一种替代方案,用来替换我们过去编写的大量冗余代码,就像JBNizet在这里展示的那样。它们的使用方式没有任何区别。 - Joffrey
7
关于多线程,你可以免费获得的是并行流:例如hugeList.parallelStream().map(s -> s.toUpperCase()).collect(toList())会将所有字符串转换为大写,并使用多个线程。但这与Lambda没有严格的联系。Lambda只是创建新的函数、谓词、消费者等实例的一种很好的新方式,这些实例被新的Stream API所使用。 - JB Nizet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接