I'm currently working on a Spring Boot 3.2 application with Java 21, and I've enabled virtual threads for improved performance. However, I’m noticing that many platform threads are still being created, which seems contrary to the benefits of using virtual threads.
Here is a snippet of my code where I am using the RestClient for making HTTP requests:
@RestController
@RequestMapping("weather")
public class WeatherController {
@Autowired
private final RestClient restClient;
@GetMapping("{countryCode}")
public Weather getWeather(@PathVariable String countryCode){
return this.restClient.get()
.uri("{countryCode}", countryCode)
.retrieve()
.body(Weather.class);
}
}
@Configuration
public class ClientConfig {
@Bean
public RestClient weatherServiceClient(@Value("${weather.service.url}") String baseUrl) {
return RestClient.builder()
.baseUrl(baseUrl)
.build();
}
}
I have enabled virtual threads in my application, but when I inspect it using jvisualvm, I still see that many platform threads are being created (HttpClient Threads).
To ensure that your RestClient is using virtual threads and to address the issue of seeing many platform threads, you need to configure the RestClient to use a virtual thread executor. By default, the RestClient uses a platform thread pool for HTTP requests, so you need to override this with a virtual thread executor.
Here’s how you can configure your RestClient to use virtual threads:
@Configuration
public class ClientConfig {
@Bean
public RestClient weatherServiceClient(@Value("${weather.service.url}") String baseUrl) {
return RestClient.builder()
.baseUrl(baseUrl)
.requestFactory(new JdkClientHttpRequestFactory(
HttpClient.newBuilder()
.executor(Executors.newVirtualThreadPerTaskExecutor()) // Configure to use virtual threads
.build()))
.build();
}
}