I have a method that will be rarely called. This method collect garbage in db. I don't want to make user to wait for server response so i decided to call this method from new thread from my service layer. i'm using Spring. Service class:
@Service
@Transactional
public class UploadService {
@Resource(name = "UploadDAO")
private UploadDao uploadDao;
Method that i don't want to wait for
public void collectBlobGarbage(){
Thread th = new Thread(new Runnable() {
@Override
public void run() {
uploadDao.collectBlobGarbage();
}
});
th.start();
}
Is it a good way to do like this?
An Executor can be used to start the thread at any point throughout the application's execution. Loading cached data as a Spring application boots up is one example. To accomplish this, the Executor call would be made in the Spring Boot application's main method, prior to the SpringApplication. run().
Starting a Thread With a Runnable Thread thread = new Thread(runnable); thread. start();
The start() method of thread class is used to begin the execution of thread.
A service layer is a layer in an application that facilitates communication between the controller and the persistence layer. Additionally, business logic is stored in the service layer. It includes validation logic in particular. The model state is used to communicate between the controller and service layers.
If you have Spring on your classpath you might as well use @Async
@Async
public CompletableFuture<Void> collectBlobGarbage() throws InterruptedException {
CompletableFuture.completeFuture(uploadDao.collectBlobGarbage());
}
On your main class you need to use @EnableAsync
like:
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
And you need an executor bean:
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("Stackoverflow-");
executor.initialize();
return executor;
}
I think the provided solution can potentially cause a lot of threads on you server.
As an alternative, you can consider using Executors.newSingleThreadExecutor
in such a way that you will get an executor service that is limited only to one thread—so you will never create more than one thread—and that is what you need.
Also as you are using Spring, consider configuring a SingleThreadExecutor
instantiation as a separate bean—in such a way that you will be able to change the implementation of ExecutorService
in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With