线程定时任务

最近有遇到定时任务的场景,本来想直接整个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/

猜你喜欢

转载自blog.csdn.net/SHIYUN123zw/article/details/82704385