Spring--定時器的應用

需求:作一個定時掃描的任務,每隔一段時間去掃描某個路徑下的xml文件。
分析:項目啓動時,就應該啓動定時掃描任務,在這裏用到了spring的定時器。
我這裏採起繼承QuartzJobBean的方式,任務類以下
#1.XmlScanImportTask.javajava

package com.scan;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/3/9 0009.
 */
public class XmlScanImportTask extends QuartzJobBean{

    private  boolean runningFlag=false;
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //指定須要執行的任務
        System.out.println("-------系統-------->當前時間:"+ new Date());
        if(runningFlag){
            LogUtil.info("掃描xml任務正在執行中...");
            return;
        }
        runningFlag = true;
        try {
            //這裏實現本身的業務
        }catch (Exception e){
            e.printStackTrace();
            LogUtil.error("掃描入庫出現異常");
        }finally {
            runningFlag = false;
            LogUtil.info("掃描任務執行完畢");
        }
    }
}

#2.xml配置以下
scan.xmlspring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <!-- 任務bean-->
    <bean id="jobDetailFactoryBean" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.scan.XmlScanImportTask"/>
    </bean>

    <!-- 觸發bean,設置任務的調度策略-->
    <bean id="cronTriggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetailFactoryBean"/>
        <!-- 每一個60秒觸發 -->
        <property name="cronExpression" value="0/60 * * * * ?"/>
    </bean>

    <!-- 調度工廠bean,激活觸發器,啓動quartz任務-->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTriggerFactoryBean"/>
            </list>
        </property>
    </bean>

</beans>

#3.線程池管理工具類以下數組

package com.scan;

import com.zving.framework.utility.LogUtil;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by Administrator on 2017/3/10 0010.
 */
public class ThreadPoolManager {
    //消息任務ID
    private static long _next_task_id = 0;
    //默認初始化線程數
    public static final int DEFAULT_THREAD_NUM = 20;
    //默認最大併發線程數
    public static final int MAX_THREAD_NUM = 20;
    //當前使用最大併發線程數
    public int _cur_thread_num = 0;
    //線程池狀態
    public boolean _is_closed = true;
    //線程任務列表
    public List<ThreadTask> taskQueue = Collections.synchronizedList(new LinkedList<ThreadTask>());
    //線程數組集合
    public WorkThread[] threads;
    //線程對象
    private  static ThreadPoolManager _instance = null;


    //默認構造
    private ThreadPoolManager(){
        _cur_thread_num = DEFAULT_THREAD_NUM;
        threads = new WorkThread[_cur_thread_num];
        for(int i = 0; i < _cur_thread_num; ++ i){
            threads[i] = new WorkThread(i);
        }
    }
    //自定義線程數構造
    public ThreadPoolManager(int thread_num){
        _cur_thread_num = thread_num;
        threads = new WorkThread[_cur_thread_num];
        for(int i = 0; i < _cur_thread_num; ++ i){
            threads[i] = new WorkThread(i);
        }
    }

    /* singleton */
    public static ThreadPoolManager getInstance(){
        if(_instance == null){
            synchronized(ThreadPoolManager.class){
                if(_instance == null){
                    _instance = new ThreadPoolManager();
                }
            }
        }
        return _instance;
    }

    public static synchronized long generateTaskId(){
        // _next_task_id += (_next_task_id + 1) / 1000000;
        // if(_next_task_id == 0) _next_task_id ++;
        return _next_task_id++;
    }
    //開啓執行
    public synchronized void start(){
        if(!_is_closed){
            LogUtil.info("線程池已經被初始化過...");
            return ;
        }
        _is_closed = false;
        //  LogUtil.info(String.format("ThreadPool Initializing----"));
        for(int i = 0; i < _cur_thread_num; ++ i){
            threads[i].start();
            //   LogUtil.info(String.format("thread [%d] start!", i));
        }
        //LogUtil.info(String.format("ThreadPool Initialized----,init "+_cur_thread_num+" thread"));
    }
    //關閉
    public void close(){
        if(!_is_closed){
            waitforfinish();
            _is_closed = true;
            taskQueue.clear();
        }
        LogUtil.info("Thread pool close!");
    }

    public void waitforfinish(){
        synchronized(this){
            _is_closed = true;
            notifyAll();
        }
        for(int i = 0; i < _cur_thread_num; ++ i){
            threads[i].stopThread();
            LogUtil.info(String.format("Thread [%d] stop!", i));
        }
    }
    //增長新任務
    public void addTask(ThreadTask new_task){

        synchronized(taskQueue){
            if(_is_closed){
                start();
            }
            if(new_task != null){
                taskQueue.add(new_task);
                taskQueue.notifyAll();
                //taskQueue.notify();
            }
        }
    }

    public int getTaskCount(){
        return taskQueue.size();
    }

    private class WorkThread extends Thread{
        private int _index;
        private boolean _is_running = true;
        public WorkThread(int index){
            _index = index;
        }

        public void run(){
            while(_is_running){
                ThreadTask t = getTask();
                if(t != null){
                    t.run();
                    //   System.out.println(_index);
                }else{
                    // 結束線程
                    LogUtil.info(String.format("thread [%d] exit", _index));
                    return;
                }
            }
        }

        public ThreadTask getTask(){
            if(_is_closed) return null;
            ThreadTask r = null;
            synchronized (taskQueue) {
                while (taskQueue.isEmpty()) {
                    try {
                        /* 任務隊列爲空,則等待有新任務加入從而被喚醒 */
                        taskQueue.wait();
                    } catch (InterruptedException e) {
                        LogUtil.error(e.getStackTrace());
                    }
                }

                /* 取出任務執行 */
                r = (ThreadTask) taskQueue.remove(0);
                return r;
            }
        }

        public void stopThread(){
            _is_running = false;
            try{
                join();
            }catch(InterruptedException ex){
                LogUtil.error(ex.getStackTrace());
            }
        }
    }
}

#3.任務線程以下spring-mvc

package com.scan;

/**
 * Created by Administrator on 2017/3/10 0010.
 */
public abstract class ThreadTask implements Runnable{

    public long taskId = 0;

    public ThreadTask() {
    }

    public ThreadTask(long taskId) {
        this.taskId = taskId;
    }

    public long getTaskId() {
        return taskId;
    }

    public void setTaskId(long taskId) {
        this.taskId = ThreadPoolManager.generateTaskId();
    }
}

#4.實際業務任務線程以下
XmlScanImportThread.java併發

public class XmlScanImportThread extends ThreadTask{

    String abfilePathTmp;
    Long siteIdTmp;

    public XmlScanImportThread(String abfilePathTmp, Long siteIdTmp) {
        this.abfilePathTmp = abfilePathTmp;
        this.siteIdTmp = siteIdTmp;
    }

    @Override
    public void run() {
        try {
            //實際業務
        }catch (Exception e){
            LogUtil.info("["+abfilePathTmp+"]解析失敗");
        }
    }
}
相關文章
相關標籤/搜索