1. 程式人生 > >執行緒定時任務

執行緒定時任務

最近有遇到定時任務的場景,本來想直接整個quartz,但是小場景不用大動作,就網上搜搜部落格,摘了幾個好的試了試,都挺好使。簡單記錄下學習學習.

 

1、Thread + sleep 最簡單實現

class ThreadTask extends Thread{
		public void run() {
			while(true) {
				try {
					
					// to do task
					
		            Thread.sleep(1*60*1000);
		            
				} catch (Exception e) {
					
				}
			}
		}
	}


// 直接開啟執行緒

2、Timer + TimerTask ,注意Schedule() 和 scheduleAtFixedRate() 區別

    @PostConstruct
	public void init() {
		//開啟執行緒
		testSchedule();
		scheduleAtFixedRate();
	}
	
	/**
	 * 耗時任務結束後,按照正常間隔執行,固定延時
	 */
	private void testSchedule() {
		TimerTask task = new TimerTask(){
			@Override
			public void run() {
				try {
						
					// to do task
						
				} catch (Exception e) {
				}
			}
		};
		
		Long delay = 60 * 1000L;
		Long period = 10 * 1000L;
		Timer timer = new Timer();
		timer.schedule(task, delay, period); //延時60s 首次執行,後擱10s 執行一次
		
	}
	
	/**
	 * 耗時任務結束後, 直接補上耗時期間所欠下的任務,固定頻率
	 */
	private void scheduleAtFixedRate() {
		
		TimerTask task = new TimerTask(){
			@Override
			public void run() {
				try {
						
					// to do task
						
				} catch (Exception e) {
				}
			}
		};
		
		Long delay = 60 * 1000L;
		Long period = 10 * 1000L;
		Timer timer = new Timer();
		//延時60s 首次執行,後擱10s 執行一次
		timer.scheduleAtFixedRate(task, delay, period);
		
		/*** 定製每日1:00執行方法 ***/
        long PERIOD_DAY = 24*60*60*1000;
		Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
         
        //執行定時任務的時間 < 當前的時間
        // 則定時任務的時間+1,以便此任務在下個時間點執行。如果不加一天,任務會立即執行。
        Date date=calendar.getTime(); 
        if (date.before(new Date())) {
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            date = calendar.getTime();
        }
       
		Timer timer2 = new Timer();  
		timer2.scheduleAtFixedRate(task,date,PERIOD_DAY);
	}

3、執行緒池 

@PostConstruct
	public void init() {
		testScheduledExecutorService()
	}
	
	public void testScheduledExecutorService() {
		Runnable runnable = new Runnable() {  
            public void run() {  
            	try {
					
            		// to do task
            		
				} catch (Exception e) {
					
				}
            }  
        };  
		
        ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
        
        /*** 延時60s執行,週期10s ***/
        service.scheduleAtFixedRate(runnable, 60*1000, 10*1000, TimeUnit.MILLISECONDS);
        
        /*** 定製每日1:00執行方法 ***/
        long oneDay = 24 * 60 * 60 * 1000;
        long initDelay  = getTimeMillis("01:00:00") - System.currentTimeMillis();
    	initDelay = initDelay > 0 ? initDelay : oneDay + initDelay;
        service.scheduleAtFixedRate(runnable, initDelay, oneDay, TimeUnit.MILLISECONDS);

	}
	
	private static long getTimeMillis(String time) {
		try {
			DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
			DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd");
			Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time);
			return curDate.getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}
	

4、spring 的 ThreadPoolTaskScheduler 

4.1 SchedulerConfiguration配置類

@Configuration
//@EnableAsync
public class SchedulerConfiguration {
	// + @EnableAsync 可解決耗時問題
	@Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        return taskScheduler;
    }
}

4.2 任務task

@Component
// @Async
//@PropertySource(value = "classpath:application.yml") 可省略
public class Task {
	/**
	 * 延時載入,耗時任務,會影響載入!
	 * + @Async  可解決耗時任務
	 */
	
	
	/*** 週期10s ***/
	@Scheduled(cron = "*/10 * * * * ?")
	public void task() {
		
		// to do task 
		
	}
	
	/*** 定製每日1:00執行方法 ***/
	@Scheduled(cron = "0 0 1 1/1 * ?")
	public void task2() {
		
		// to do task 
		
	}

    //@Scheduled(cron = "${task.cron}") 把cron寫在配置檔案中
	public void task3() {
		
		// to do task 
		
	}

}

5、spring 的 ThreadPoolTaskExecutor

5.1 配置類 AsyncConfiguration

@Configuration
@EnableAsync
public class AsyncConfiguration {
	
	private int corePoolSize = 10;
	
	private int maxPoolSize = 100;
	
	private int queueCapacity = 20;
	
	@Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }

}

5.2 任務 task

@Component
@Async
public class Task {
	
	
    /**
     * 非同步可解決耗時問題
     * 
     */


	/*** 週期10s ***/
	@Scheduled(cron = "*/10 * * * * ?")
	public void task() {
		
		// to do task 
		
	}

	/*** 定製每日1:00執行方法 ***/
	@Scheduled(cron = "0 0 1 1/1 * ?")
	public void task2() {
		
		// to do task 
		
	}

}

 

參考部落格:

https://blog.csdn.net/u010963948/article/details/52946268

https://blog.csdn.net/a718515028/article/details/80396102

 

線上cron  http://cron.qqe2.com/