gpt4 book ai didi

java - 在没有线程暂停的情况下执行 ExecutorService 中的任务

转载 作者:行者123 更新时间:2023-12-05 02:28:57 24 4
gpt4 key购买 nike

我有一个有8个线程的线程池

private static final ExecutorService SERVICE = Executors.newFixedThreadPool(8);

我的机制模拟 100 个用户(100 个任务)的工作:

List<Callable<Boolean>> callableTasks = new ArrayList<>();
for (int i = 0; i < 100; i++) { // Number of users == 100
callableTasks.add(new Task(client));
}
SERVICE.invokeAll(callableTasks);
SERVICE.shutdown();

用户执行生成文档的任务。

  1. 获取任务的UUID;
  2. 每 10 秒获取一次任务状态;
  3. 如果任务准备就绪,获取文档。
public class Task implements Callable<Boolean> {

private final ReportClient client;

public Task(ReportClient client) {
this.client = client;
}

@Override
public Boolean call() {
final var uuid = client.createDocument(documentId);
GetStatusResponse status = null;
do {
try {
Thread.sleep(10000); // This stop current thread, but not a Task!!!!
} catch (InterruptedException e) {
return Boolean.FALSE;
}
status = client.getStatus(uuid);
} while (Status.PENDING.equals(status.status()));
final var document = client.getReport(uuid);
return Boolean.TRUE;
}
}

我想把空闲时间(10 秒)给另一个任务。但是当命令Thread.sleep(10000);被调用时,当前线程暂停执行。前 8 个任务暂停,92 个任务等待 10 秒。如何同时执行 100 个正在进行的任务?

最佳答案

Answer by Yevgeniy对于今天的 Java,看起来是正确的。您既想吃蛋糕也想吃蛋糕,因为您希望线程在重复任务之前 hibernate ,但您还希望该线程执行其他工作。这在今天是不可能的,但在未来可能会。

Loom 项目

在当前的 Java 中,Java 线程直接映射到主机 OS线。在所有常见的操作系统中,例如 macOS、BSD、Linux、Windows 等,当在主机线程中执行的代码阻塞(停止等待 sleep 、或存储 I/O、或网络 I/O 等)时,线程也会阻塞 block 。被阻塞的线程挂起,主机操作系统通常在那个未使用的内核上运行另一个线程。但关键是挂起的线程不会执行进一步的工作,直到您对 sleep 的阻塞调用返回。

这张图在不久的将来可能会改变。 Project Loom寻求添加 virtual threads到 Java 中的并发设施。

在这项新技术中,许多 Java 虚拟线程被映射到每个主机操作系统线程。处理许多 Java 虚拟线程是由 JVM 而不是操作系统来管理的。当 JVM 检测到虚拟线程的执行代码被阻塞时,该虚拟线程被“停放”,由 JVM 搁置,另一个虚拟线程换出以在该“真实”主机操作系统线程上执行。当另一个线程从它的阻塞调用返回时,它可以被重新分配给一个“真正的”主机操作系统线程以进一步执行。在 Project Loom 下,主机操作系统线程保持忙碌,在任何挂起的虚拟线程有工作要做时从不空闲。

虚拟线程之间的这种交换非常高效,因此可以在传统计算机硬件上同时运行数千甚至数百万个线程。

使用虚拟线程,您的代码确实会像您希望的那样工作:Java 中的阻塞调用不会阻塞主机操作系统线程。但是虚拟线程是实验性的,仍在开发中,安排为 preview featureJava 19 .包含 Loom 技术的 Java 19 早期访问版本是 available now供您尝试。但对于今天的生产部署,您需要遵循 Yevgeniy 的回答中的建议。


请对我的报道持保留态度,因为我不是并发方面的专家。您可以从真正的专家、Project Loom 团队成员(包括 Ron Pressler 和 Alan Bateman)的文章、访谈和演示中听到它。

关于java - 在没有线程暂停的情况下执行 ExecutorService 中的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72426404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com