Home > front end >  @Async method inside synchronized method Java
@Async method inside synchronized method Java

Time:01-28

To summarize the problem, I am trying to call some method which is annotated with @async in a synchronized method. Reason for using @async was because I wish to return the response of the post method (to reduce waiting time on client’s side) and continue doing some post processing work (resetting certain properties). However, as the POST method involve altering a graph database, I declare the method with synchronized keyword to prevent altering of the graph database while another computation is going on. The result of this seem to be that two threads are entering the synchronized method, which shouldn’t be occurring?

@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”);
}

This will give me an output similar to something like this:

===== > In Thread: http-nio-10080-exec-2

===== > Doing some work in compute

===== > done computing

=====> Resetting in Thread: Async-1

===== > In Thread: http-nio-10080-exec-3

===== > Doing some work in compute

===== > Done Resetting

My understanding of Synchronized method is that it only allows a single thread to enter the method at any time. But it seems like there are two threads running the Synchronized compute method at the same time. I tried to come up with some reasons for this and the two main ones I could think of are:

  1. Due to different instances of the Controller class, however I recalled reading somewhere that a RESTController is a singleton scope by default, so it shouldn’t be due to this?

  2. Context switching? Does synchronized method allow for context switching from one thread to another?

I apologise if any part of my question is confusing as I am relatively new to Java Spring/Spring Boot especially the concept of concurrency, multithreading etc. Please do let me know if you need me to clarify any part of my question.

CodePudding user response:

When you call the asynchronous method reset() within the synchronized method compute() the latter method will not wait for reset() to finish. Instead it will spawn a new thread that handles the code execution of reset() and then immediately proceeds to the next line Return(“===== > done computing”). After that the method will complete. When it completes a new thread will be allowed to call compute(), even when the reset() call of the previous thread that entered compute() is still running in the separate thread.

So to be more clear, The method compute() is not entered by two threads simultaneously. It only looks that way because part of the text prints from thread http-nio-10080-exec-3 come before the Done Resetting print of thread Async-1. So your code is working as intended.

  •  Tags:  
  • Related