java - Spring异步线程 hibernate

标签 java spring spring-boot asynchronous

我有这段代码:

final Future<ApplicationUser> user = applicationUserService.findIncludePrivilegesById(id);
    while (!user.isDone()) {
        Thread.sleep(100);
    }
    if (user.get() == null) throw new Exception(this.getMessageSource().getMessage("label.error.findError",
            null, locale));
    model.addAttribute("user", new ApplicationUserDto(user.get()));

    model.addAttribute("roles", Role.valuesMinusApi());
    model.addAttribute("groups", completeAuthorityList);
    model.addAttribute("message", this.getMessageSource().getMessage("label.dialog.userEdit", new Object[]{user.get().getLogin()}, locale));
    model.addAttribute("applicationUserStates", ApplicationUserState.values());
    return "administration/edit";

applicationUserService.findIncludePrivilegesById(id) 去远程数据库服务器查询数据。
我设计这段代码的想法是让这个(耗时的数据库通信)处理池中的一个空闲线程(通过使用异步)。

据我了解整个异步这些步骤可能会发生:

  1. 主线程进入方法
  2. 线程池中的一个线程查询数据
  3. 主线程等待或有剩余资源去做“其他”事情
  4. 如果线程池线程结束,我可以使用结果

我真的可以从这种情况中获益吗,因为我必须在每种情况下都等待结果(调用异步或同步的服务方法)?
使用 Thread.sleep() 是一种好习惯吗?

从这个例子中我能想到的唯一好处是主线程可以空闲(不阻塞)用于其他计算(可能处理其他网络请求),而线程池线程执行耗时的过程?

最佳答案

Do i really profit from this scenario as i have to wait for the results in every case (calling the service method async of sync)?

没有。您所创建的本质上仍然是一个阻塞调用,但您已经使其比简单的阻塞调用复杂得多:

ApplicationUser user = applicationUserService.findIncludePrivilegesById(id);

它也使用 2 个线程而不是 1 个,但您仍然只做 1 件事。第二个线程正在执行伪 busy-waiting基本上只问另一个线程“我们到了吗?”每 100 毫秒。

如果您的主线程除了 sleep() 之外还有其他实际工作要做(例如,执行对不同服务器的第二次慢速调用),那么上面的代码会有一些优点。但即便如此,它也会使代码变得困惑,因为它在特殊情况下进行手动多线程处理。一个小的重新设计可能是更好的选择。

Is it good practise to use Thread.sleep()?

没有。几乎没有理由调用 Thread.sleep() 除非您想暂停一个线程(这在大多数情况下是非常不必要的)。如果您正在考虑使用 Thread.sleep(),您应该重新考虑您在做什么。

最后,你正在做的半忙等待

while (!user.isDone()) {
    Thread.sleep(100);
}

可以仅替换为 user.get(),它将阻塞(即 sleep )直到另一个线程完成。这会更有效(和同步)。因此,您无法从当前代码中获得任何好处。

如果您只是担心通话时间过长,并且想利用这段时间做点什么,别担心。该线程将处于等待状态,并且将有其他线程运行。如果您遇到的情况是您的所有线程都在该调用上被阻塞,导致资源实际耗尽,那么也许是时候看看为什么执行该调用需要这么长时间了?

现在有一些方法可以执行非阻塞调用以实际获得您正在考虑的一些好处,但这些需要来自 libraries 的支持和 drivers ,并且需要一种不同的编程方式,而无需求助于线程池或 Futures

关于java - Spring异步线程 hibernate ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64648458/

相关文章:

用于测试和生产的 Spring 属性替换

java - 如何在 Spring Boot Webflux 中克隆 ServerResponse

java - 为什么在 java.util.Collections 中声明静态 java.util.Collections.fill() 方法而不是在 java.util.AbstractList 中声明实例方法?

java - 严重: Exception sending context initialized event to listener instance of class [org. springframework.web.context.ContextLoaderListener]

java - RequestMethod.DELETE 不接受 RequestBody

java - 在 Apache Camel 中从 Json 检索对象

java - 如何从 jsp :include or tiles? 调用 struts Action

java - arraylist中add和set的区别

java - Spring Security - antMatcher 的 POST 方法(不是 antMatchers)

java - 使用 AspectJ 拦截请求范围内的所有 JDBC 调用并作为响应返回