V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  soarchen  ›  全部回复第 1 页 / 共 1 页
回复总数  2
2023-10-21 09:38:53 +08:00
回复了 BarackLee 创建的主题 Java ChatGPT 无法解开的 Java 多线程题
为了更好地解释这两段代码,我们首先需要了解 Java 中`ExecutorService`和线程的工作方式。

`Executors.newSingleThreadExecutor()`返回一个使用单一工作线程操作的执行程序,可以保证任务按提交的顺序执行。

#### 代码 1

1. 主线程开始执行。
2. 主线程启动一个新的线程执行`service.execute()`内的 Lambda 表达式。
3. 新线程进入一个无限循环,每次循环都会调用`hello2()`方法,然后线程休眠 1 秒。
4. `hello2()`方法只是一个简单的封装,实际调用`hello()`方法。
5. `hello()`方法中,一个新的`Runnable`任务被提交给`ExecutorService`。这意味着它请求`ExecutorService`以后某个时间点运行这个任务。但是请注意,这个执行程序是一个`newSingleThreadExecutor()`,所以它只有一个线程。
6. 而由于`service.execute()`已经持续占用这个唯一的线程(因为它在一个无限循环中),提交给执行程序的任务从不得到执行机会。
7. 因此,代码 1 永远不会打印“hello world”。

#### 代码 2

1. 主线程开始执行。
2. 主线程启动一个新线程执行`service.execute()`内的`Runnable`任务。
3. 这个新线程调用`hello2()`,然后`hello2()`调用`hello()`。
4. 和上面一样,`hello()`中提交了一个新的`Runnable`任务给`ExecutorService`。
5. 但这次,由于没有无限循环占用执行器的唯一线程,所以提交的任务会被执行。
6. 但请注意:新提交的任务在执行时又会调用`hello2()`,这意味着它会重新提交自己。因此,这个任务会无限次地重新提交并打印“hello world”。

结论:

问题 1: 代码 1 不会打印“hello world”,因为新提交的任务从未得到执行机会。
问题 2: 代码 2 会无限次地打印“hello world”,因为任务会不断地重新提交自己并得到执行。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1806 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 00:02 · PVG 08:02 · LAX 16:02 · JFK 19:02
Developed with CodeLauncher
♥ Do have faith in what you're doing.