Start background thread using spring on startup

In this tutorial we will start a thread on the application startup using spring bean.So we will start the thread using @PostConstruct annotation on the method. So this makes sure that the annotated method is called before the Spring bean is put into service.  And we will be using executor service to start a thread. Here is the method

@PostConstruct
public void init() {
  BasicThreadFactory factory = new BasicThreadFactory.Builder()
        .namingPattern("myspringbean-thread-%d").build();

  executorService =  Executors.newSingleThreadExecutor(factory);
  executorService.execute(new Runnable() {
   @Override
   public void run() {
    try {
     // do something
     System.out.println("thread started");
    } catch (Exception e) {
     logger.error("error: ", e);
    }
   }
  });
  executorService.shutdown();
}

Let me explain what I am doing in the above method. I am using BasicThreadFactory so that thread has a name and would be easy while reading logs to find out which thread is doing which task. You can start the thread without it, like below.

executorService =  Executors.newSingleThreadExecutor(factory);

So in the thread I am just printing out something. This can be replaced by your custom code.
And the executorService.shutdown() makes sure that thread is executed. And this method does not wait for the thread to finish.

And finally let us look to have a graceful shutdown in case spring bean is destroyed while the thread is executing. This is done using the @PreDestroy annotation.Here is the method.

@PreDestroy
public void beandestroy() {
  if(executorService != null){
   executorService.shutdownNow();
  }
 }

So this method calls executorService.shutdownNow(); which tries to stop the threads immediately. You can see in the javadocs of this method that it only makes the best effort to shutdown.

Now let us have the whole picture and here goes the bean. You can see how simple it is.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

@Component
public class MySpringBean {

 private static final Logger logger = org.apache.logging.log4j.LogManager
   .getLogger(MySpringBean.class);

 private ExecutorService executorService;

 @PostConstruct
 public void init() {

  BasicThreadFactory factory = new BasicThreadFactory.Builder()
    .namingPattern("myspringbean-thread-%d").build();

  executorService = Executors.newSingleThreadExecutor(factory);
  executorService.execute(new Runnable() {

   @Override
   public void run() {
    try {
     // do something
     System.out.println("thread started");
    } catch (Exception e) {
     logger.error("error: ", e);
    }
   }
  });

  executorService.shutdown();

 }

 @PreDestroy
 public void beandestroy() {
  if (executorService != null) {
   executorService.shutdownNow();
  }
 }

}

If you are doing some IO operations in your threads please have a look at the post. 

1 thought on “Start background thread using spring on startup”

  1. Nice article. It happens to be exactly what I need right now. Extra credit for naming the thread and including clean shutdown.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.