java uses Queue to execute tasks asynchronously in queues

Posted by patnet2004 on Sat, 30 Nov 2019 09:36:48 +0100

First, create a total Handler (queue unified processing interface), which is called QueueTaskHandler

public interface QueueTaskHandler {

    void processData();
}

Then write a queue service class, and don't explain it much. My comments are very clear

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

@Component
public class QueueGenerationService{

    // Log monitoring
    private static final Logger log = LoggerFactory.getLogger(QueueGenerationService.class);
    // Configure by yourself according to business and server performance. Here I configure up to 50000 tasks
    // LinkedBlockingQueue If no size is specified during construction, the default size is Integer.MAX_VALUE
    private final LinkedBlockingQueue<QueueTaskHandler> tasks = new LinkedBlockingQueue<QueueTaskHandler>(50000);
    // Similar to a thread manager, which ensures that all tasks are in the queue
    private ExecutorService service = Executors.newSingleThreadExecutor();
    // Check if the service is running
    private volatile boolean running = true;
    //Thread state
    private Future<?> serviceThreadStatus = null;

    @PostConstruct
    public void init() {
    serviceThreadStatus = service.submit(new Thread(new Runnable() {
        @Override
        public void run() {
        while (running) {
            try {
            //Start a task
            QueueTaskHandler task = tasks.take();
            try {
                task.processData();
            } catch (Exception e) {
                log.error("Task processing error", e);
            }
            } catch (InterruptedException e) {
            log.error("Service stop, exit", e);
            running = false;
            }
        }
        }
    }, "save data thread"));
    }

    public boolean addData(QueueTaskHandler dataHandler) {
    if (!running) {
        log.warn("service is stop");
        return false;
    }
    //offer When the queue is full and cannot be added again
    boolean success = tasks.offer(dataHandler);
    if (!success) {
        log.warn("Failed to add task to queue");
    }
    return success;
    }

    public boolean checkServiceRun() {
    return running && !service.isShutdown() && !serviceThreadStatus.isDone();
    }

    public void activeService() {
    running = true;
    if (service.isShutdown()) {
        service = Executors.newSingleThreadExecutor();
        init();
        log.info("Close thread pool, reinitialize thread pool and tasks");
    }
    if (serviceThreadStatus.isDone()) {
        init();
        log.info("End of thread pool task, reinitialize task");
    }
    }

    @PreDestroy
    public void destory() {
    running = false;
    service.shutdownNow();
    }
}

Then you can start writing your business Handler

public class TestServiceHandler implements QueueTaskHandler {

    // ******* start This paragraph is not necessary. It is a way to demonstrate the value transmission
    private String name;

    private Integer age;

    public TestServiceHandler(String name) {
    this.name = name;
    }

    public TestServiceHandler(Integer age) {
    this.age = age;
    }

    public TestServiceHandler(String name, Integer age) {
    this.name = name;
    this.age = age;
    }

    // ****** end

    // This is what we achieved QueueTaskHandler Processing interface of
    @Override
    public void processData() {
    // You can do what you want
    // Reference is needed here spring Of service If so, I wrote a tool class, which will be posted below
    // ItestService testService = SpringUtils.getBean(ItestService.class);
    System.out.println("name > " + name + "," + "age > " + age);
    }

}

Let's add a task to the service

    // Inject queue service here
@Autowired
private QueueGenerationService queueGenerationService;

  // Method of calling and passing reference in method
  queueGenerationService.addData(new TestServiceHandler("Xiao Ming",5));
 

The whole process is over. Then if you need to use other bean s such as service in your business Handler, please try this utility class I wrote

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    /**
     * @return
     * @Description Get applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtils.applicationContext == null) {
            SpringUtils.applicationContext = applicationContext;
        }
    }

    /**
     * @param name
     * @return
     * @Description Get Bean through name
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * @param clazz
     * @return
     * @Description Get Bean through class
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * @param name
     * @param clazz
     * @return
     * @Description Return the specified Bean through name and Clazz
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

If you have any questions or comments, please leave a message below and the landlord will reply when you see it. Thank you.

Topics: Java Spring