24、Java中如何实现一个定时任务

在实际开发中经常用到定时任务,如定时清理数据,备份数据,报表统计等。java中怎么实现定时任务呢?

1、通过线程,定时睡眠方法执行定时任务

     创建一个thread,在它在run方法里面写个while循环一直运行着,在循环体内部写个thread.sleep睡眠一段时间来达到定时任务的效果。这样使用起来很方便但是缺点很多。比如:不方便设计到具体时间点运行。

 new Thread(new Runnable() {	
	 		@Override
	 		public void run() {
	 			while(true){
	 				try {
		 				System.out.println("show time="+System.currentTimeMillis());
		 				Thread.sleep(1000);
		 			} catch (InterruptedException e) {
		 				e.printStackTrace();
		 			}
	 			}
	 		}
	 	   }).start();

2、通过Java.util中的timer 和timerTask实现定时任务。

    相比与使用线程定时睡眠,好处是可以控制启动任务和取消任务,可以设置执行延时,可以设计到具体时间点启动,可以设置运行频率。

		long delay=1000;
		long  period=1000;
		Timer tr=new Timer();
		tr.schedule(new TimerTask() {
	               int i=0;
			@Override
			public void run() {
				if(i++==5){tr.cancel();}
			  	System.out.println(System.currentTimeMillis());
			}
		}, delay,period);

 还可以作为守护线程运行: 实现方式 new Timer(true)    true 说明这个timer以daemon方式运行 

什么是守护线程呢?  

 用个比较通俗的说法,任何一个守护线程都是整个JVM中所有非守护线程的保姆:

只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。

Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。

3、通过线程池的ScheduledExecutorService执行定时任务

他是Executors的静态方法,Executors常用的有四个生成线程池的静态方法,其他三个分别是:
newSingleThreadpool():单线程池,同时只有一个线程在跑。 
newCachedThreadPool() :回收型线程池,可以重复利用之前创建过的线程,运行线程最大数是Integer.MAX_VALUE。 
newFixedThreadPool() :固定大小的线程池,跟回收型线程池类似,只是可以限制同时运行的线程数量 
我们重点说下scheduledExecutorService,他和timer的区别是:
Timer的内部只有一个线程,如果有多个任务的话就会顺序执行,这样我们的延迟时间和循环时间就会出现问题。

ScheduledExecutorService是线程池,所以就不会出现这个情况,在对延迟任务和循环任务要求严格的时候,就需要考虑使用ScheduledExecutorService了。

  • long initialDelay=1000;
    		long period=2000;
    		ScheduledExecutorService st=Executors.newSingleThreadScheduledExecutor();
    		st.scheduleAtFixedRate(new Runnable() {
    			@Override
    			public void run() {
    				System.out.println(System.currentTimeMillis());
    				
    			}
    		}, initialDelay, period, TimeUnit.MILLISECONDS);
    4、除此之外还有一些常用的框架可以使用   


  •  Spring 定时任务  springTaskTimer

  •  Quartz  是一个使用频率非常高的框架,他的优点也很突出:

    Quartz支持Cron表达式定义时间点也支持SimpleTrigger对应时间点,可以很精确的定义时间点。
    Quartz支持集群,可以在多个服务器(连同一个数据库)自动分配到不同的服务器上执行。
    Quartz支持多种错误处理形式(如错误后下次不执行、马上重新执行、下次继续执行等)
    Quartz支持多种漏触发处理(如关机漏触发情况)


******如果需要可以打开蜻蜓FM搜索”java面试题“收听音频面视题****

猜你喜欢

转载自blog.csdn.net/zhangkang65/article/details/81040298