基於springboot實現輪詢線程自動執行任務


 

本文使用:

  Timer:這是java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務。使用這種方式可以讓你的程序按照某一個頻度執行,

但不能在指定時間運行。一般用的較少。

類似於quartz任務調度: demo地址 lsr-core-base模塊中

直接上代碼:

線程基類:

package cn.lsr.core.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @Description: 輪詢線程基類
 * @Package: lsr-microservice
 * @author: Hacker_lsr@126.com
 **/
public abstract class AbstractPollThread {
    private static final Logger log = LoggerFactory.getLogger(AbstractPollThread.class);
    private long delay = 60; // 延期時間(第一次執行時間-調用時間)
    private long timeInterval = 60; //時間間隔(s)
    private Timer timer;
    private Timestamp lastProcess = null; //上次執行的時間
    private boolean isTimerStart = false; //定時器是否啟動
    private boolean isOnProcessing = false; //是否在執行處理
    private final String threadName; //線程名稱
    private final String threadId; //線程標識
    private final String longname; //中文名稱
    private long processCount = 0; //執行次數
    private long processTime = 0; //已運行時間
    private long errorProcessCount = 0; //執行失敗的次數

    public AbstractPollThread(String threadId, String threadName, String longname, Long delay, Long timeInterval) {
        this.threadId = threadId;
        this.threadName = threadName;
        this.longname = longname;
        if (timeInterval != null && timeInterval > 0)
            this.timeInterval = timeInterval;

        if (delay != null)
            this.delay = delay;
        PollThreadManager.get().register(threadName, this);
    }
    /**
     * 線程啟動時回調方法。
     */
    public void init() {

    }

    /**
     * 輪詢間隔回調方法。
     */
    public abstract void process();

    /**
     * 啟動方法
     */
    public void startup() {
        this.timer = new Timer( "lsr-timer-" + this.threadName, false);
        try {
            this.timer.schedule(new TimerTask() {
                boolean initialized = false;
                @Override
                public void run() {
                    // 異步線程資源清理
                    //清理完上下文數據,在打log4j標記
                    log.info("--------------------輪訓線程[" + AbstractPollThread.this.threadName + "]開始調度--------------------");
                    // 2015.4.20 每個線程開始受理請求時對數據庫連接進行檢查,若不可用則重連一次
                    long start = System.currentTimeMillis();
                    try {
                        AbstractPollThread.this.isOnProcessing = true;
                        AbstractPollThread.this.lastProcess = new Timestamp(System.currentTimeMillis());
                        AbstractPollThread.this.process();
                        AbstractPollThread.this.isOnProcessing = false;
                    }
                    catch (Throwable t) {
                         log.error("輪詢線程出現異常", t);
                        AbstractPollThread.this.errorProcessCount++;
                    } finally {
                        AbstractPollThread.this.processCount++;
                        AbstractPollThread.this.processTime = AbstractPollThread.this.processTime + System.currentTimeMillis() - start;
                        log.info("--------------------輪訓線程[" + AbstractPollThread.this.threadName + "]調度結束. [" + (System.currentTimeMillis() - start) + "]--------------------");
                        //  異步線程資源清理
                    }
                }
            }, this.delay * 1000, this.timeInterval * 1000);
            this.isTimerStart = true;
        } catch (Exception e) {
            this.isTimerStart = false;
            log.error("輪詢線程設置定時器失敗,", e);
            throw new RuntimeException("輪詢線程設置定時器失敗", e);
        }
    }

    public void shutdown() {
        try {
            if (this.timer != null)
                this.timer.cancel();
            this.isTimerStart = false;
        } catch (Exception e) {
            this.isTimerStart = false;
            log.error("關閉輪詢線程中的定時器失敗", e);
            throw new RuntimeException("關閉輪詢線程中的定時器失敗", e);
        }
    }

    public String getThreadName() {
        return this.threadName;
    }

    public String getLongname() {
        return this.longname;
    }

    public long getProcessCount() {
        return this.processCount;
    }

    public long getProcessTime() {
        return this.processTime;
    }

    public long getErrorProcessCount() {
        return this.errorProcessCount;
    }

    public void setTimeInterval(long timeInterval) {
        this.timeInterval = timeInterval;
    }

    public long getTimeInterval() {
        return this.timeInterval;
    }

    public boolean isTimerStart() {
        return this.isTimerStart;
    }

    public boolean isOnProcessing() {
        return this.isOnProcessing;
    }

    public String getLastProcessTime() {
        return this.lastProcess == null ? null : this.lastProcess.toString();
    }

    public void resetCountInfo() {
        this.processCount = 0;
        this.processTime = 0;
        this.errorProcessCount = 0;
        this.lastProcess = null;
    }

}

輪詢線程配置類:

package cn.lsr.core.thread;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @Description: 輪詢線程配置
 * @Package: lsr-microservice
 * @author: Hacker_lsr@126.com
 **/
public class PollThreadConfig {
    /**
     * 輪詢線程ID
     */
    private String threadId;

    /**
     * 輪詢線程名稱
     */
    private String threadName;

    /**
     * 間隔時間
     */
    private Long timeInterval;

    /**
     * 輪詢線程首次延遲時間
     */
    private Long delay;

    // get set 省略

}

線程管理器:

package cn.lsr.core.thread;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: 線程管理器
 * @Package: lsr-microservice
 * @author: Hacker_lsr@126.com
 **/
public class PollThreadManager {
    private final static Map<String, AbstractPollThread> pollThreadMap = new ConcurrentHashMap<String, AbstractPollThread>();

    private final static PollThreadManager instance = new PollThreadManager();


    public static PollThreadManager get() {
        return instance;
    }

    public void register(String threadName, AbstractPollThread pollThread) {
        pollThreadMap.put(threadName, pollThread);
    }

    public AbstractPollThread getPollThread(String threadName) {
        return pollThreadMap.get(threadName);
    }

    public Map<String, AbstractPollThread> getPollThreads() {
        return pollThreadMap;
    }
}

測試線程(可擴展):

package cn.lsr.core.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;

/**
 * @Description: 測試輪詢線程
 * @Package: lsr-microservice
 * @author: Hacker_lsr@126.com
 **/
public class TestServerPollThread extends AbstractPollThread{
    private static final Logger log = LoggerFactory.getLogger(TestServerPollThread.class);
    /**
     * 插件     - OnlineServerManagerPlugin -啟動的時候初始化線程
     * @param threadId 輪詢線程ID
     * @param threadName 輪詢線程名稱
     * @param longname  中文名稱
     * @param delay 輪詢線程首次延遲時間
     * @param timeInterval 時間間隔
     */
    public TestServerPollThread(String threadId, String threadName, String longname, Long delay, Long timeInterval) {
        super(threadId, threadName, longname, delay, timeInterval);
    }

    /**
     * 輪詢間隔回調方法
     */
    @Override
    public void process() {
        log.info("刷新時間為:{}", new Timestamp(System.currentTimeMillis()));
       //邏輯
    }
}

使用:

//注入:
private TestServerPollThread testServerPollThread;
// 封裝的工具類,獲取的ioc的線程配置
PollThreadConfig pollThreadConfig = SpringUtil.getBean(PollThreadConfig.class);
testServerPollThread = new TestServerPollThread(pollThreadConfig.getThreadId(),pollThreadConfig.getThreadName(),pollThreadConfig.getThreadName(),pollThreadConfig.getDelay(),pollThreadConfig.getTimeInterval());
//調用方法
testServerPollThread.startup();

application.properties:

##################################### 輪詢線程 #######################################
#開關 lsr.poll.thread.enabled=true
#線程id lsr.poll.thread.threadId=LSRThread
#線程中文名 lsr.poll.thread.threadName=輪詢線程
#間隔時間 lsr.poll.thread.timeInterval=60
#加載延遲時間 lsr.poll.thread.delay=60


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM