【发布时间】:2022-01-26 12:27:07
【问题描述】:
为了总结这个问题,我试图在同步方法中调用一些用@async 注释的方法。使用@async 的原因是因为我希望返回 post 方法的响应(以减少客户端的等待时间)并继续做一些后期处理工作(重置某些属性)。但是,由于 POST 方法涉及更改图形数据库,因此我使用 synchronized 关键字声明该方法,以防止在进行另一次计算时更改图形数据库。这样的结果似乎是两个线程都进入了同步方法,这不应该发生?
@RestController
public class Controller {
@PostMapping(path = “/compute”)
public synchronized String compute() {
System.out.println(“===== > In thread: “ + Thread.currentThread().getName());
System.out.print(“===== > Doing some work in compute”);
ResetService.reset()
Return(“===== > done computing”)
}
@Service
public class ResetService {@Async public void reset (){
System.out.println(“===== > resetting in thread: “ + Thread.currentThread().getName());
#(resetting some properties in neo4j graph database)
resetMethod();
System.out.print(“===== > Done Resetting”);
}
这会给我一个类似于这样的输出:
===== > 在线程中:http-nio-10080-exec-2
===== > 做一些计算工作
===== > 完成计算
=====> 在线程中重置:Async-1
===== > 在线程中:http-nio-10080-exec-3
===== > 做一些计算工作
===== > 完成重置
我对Synchronized方法的理解是,它只允许单个线程随时进入该方法。但似乎有两个线程同时运行同步计算方法。我试图为此想出一些原因,我能想到的两个主要原因是:
-
由于 Controller 类的实例不同,但我记得在某处读到 RESTController 默认情况下是单例范围,所以不应该是因为这个?
-
上下文切换?同步方法是否允许从一个线程到另一个线程的上下文切换?
如果我的问题的任何部分令人困惑,我深表歉意,因为我对 Java Spring/Spring Boot 相对较新,尤其是并发、多线程等概念。如果您需要我澄清我的问题的任何部分,请告诉我。
【问题讨论】:
标签: java multithreading