JAVA多线程——定时任务实例(未完成)

定时任务

  • 功能设计
  • JAVA实现
    • 简单版实现:Timer定时器
      • 实例
    • Executor + 定时器机制
      • 实例
    • Quartz
      • 实例

功能设计

设计一个定时执行的多线程任务,具有两种功能:

  • 固定时间点运行任务
  • 以固定时间为周期运行任务

JAVA实现

简单版实现:Timer定时器

利用JAVA自带的Timer类定时器,它可以设置计划任务,也就i是在指定的时间开始执行某一个任务。它使用TimerTask来封装任务。

实例

package timer.example;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {

	public static void main(String[] args) throws InterruptedException {
		MyTask task = new MyTask();
		Timer timer = new Timer();
		
		System.out.println("当前时间:" + new Date().toLocaleString());
		// 调度一个Task,当前时间1秒后,每两秒执行一次
		timer.schedule(task, 1000,2000);
		
		Thread.sleep(10000);
		task.cancel(); // 取消当前的任务,这样开始每两秒运行一次的task就停止了
		
		System.out.println("=========================");
		
		Calendar now = Calendar.getInstance();// 获取当前时间
		now.set(Calendar.SECOND, now.get(Calendar.SECOND)+3);
		Date runDate = now.getTime();
		MyTask2 task2 = new MyTask2();
		timer.scheduleAtFixedRate(task2, runDate, 3000);
		// 固定速率,这里是指从runDate(前面定义的当前时间后3秒钟)开始执行每3秒执行一次,实际运行间隔取线程进行时间和定义间隔间最长者
		Thread.sleep(20000);
		timer.cancel(); // 取消定时器
	}

}

class MyTask extends TimerTask {// TimerTask 是继承Runnable接口的一个类
	public void run()
	{
		System.out.println("运行了!时间为:" + new Date());
	}
}

class MyTask2 extends TimerTask{
	public void run()
	{
		System.out.println("运行了!时间为:" + new Date());
		try
		{
			Thread.sleep(4000);
		} catch (InterruptedException e)
		{
			e.printStackTrace();
		}
	}
}

Executor + 定时器机制

通过加入定时器元素,使executor也能融入定时任务。
executor中,使用的线程池类为ScheduledExectorService,它可以执行定时任务和周期任务。

实例

package schedule.timerandexecutor;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledExecutorTest {

	public static void main(String[] args) throws Exception {
		executeAtFixTime(); // 利用executor框架使程序在一个指定的时间点启动
		executeAtFixRate(); // 固定速率执行,每3s执行一次
		executeAtFixDelay(); //固定延时执行,设定为延时3s执行一次,实际为4s执行一次
	}

	public static void executeAtFixTime() throws Exception{
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);// 线程池大小
		executor.schedule(
			new MyTask(), // 需要运行的任务本身
			1, // 需要延迟的时间
			TimeUnit.SECONDS); // 需要延迟的单位
		// MyTask只会执行一次就结束
		Thread.sleep(20000);
		executor.shutdown();
	}
	
	/**
	 * 
	 * 周期任务 固定速率 是以上一个任务开始的时间计时, Period时间过去后,检测上一个任务是否执行完毕
	 * 如果上一个任务执行完毕,则当前任务立即执行,如果上一个任务没有执行完毕,则需要等待上一个任务执行完毕后立即执行
	 */
	public static void executeAtFixRate() throws Exception 
	{
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
		executor.scheduleAtFixedRate(new MyTask(), 1, 3000, TimeUnit.MILLISECONDS);
		// 延迟1ms启动,每3s运行一次
		Thread.sleep(20000);
		executor.shutdownNow();
	}
	
	/**
	 * 
	 * 周期任务 固定延时 是以上一个任务结束时开始计时,period时间过去后,立即执行
	 * 所以虽然设定是3s钟后执行一次,但实际上是4s执行一次,因为执行过程需要耗费1s
	 */
	public static void executeAtFixDelay() throws Exception
	{
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
		executor.scheduleWithFixedDelay(new MyTask(), 1, 3000, TimeUnit.MILLISECONDS);
		
		Thread.sleep(20000);
		executor.shutdown();
	}
}

public class MyTask implements Runnable {

	@Override
	public void run() {
		System.out.println("时间为:" + new Date());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e)
		{
			e.printStackTrace();
		}
	}

}

Quartz

Quartz是一个较为完善的任务调度框架,来自于第三方包。它解决程序中Timer零散管理的问题,功能更加强大,比如:Timer执行周期任务,如果中间某一次有异常,整个任务终止执行;而Quartz执行周期任务,如果中间某一次有异常,不影响下次任务执行。

实例

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzTest {

	public static void main(String[] args) {
		try {
			// 创建scheduler
			Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
			
			// 定义一个Trigger
			Trigger trigger = newTrigger().withIdentity("trigger1", "group1") // 定义name/group
					.startNow() // 一旦加入scheduler,立即生效
					.withSchedule(simpleSchedule() // 使用SimpleTrigger
							.withIntervalInSeconds(2) // 每隔2秒执行一次
							.repeatForever())//一直执行
					.build();
			
			// 定义一个JobDetail
			JobDetail job = newJob(HelloJob.class) //定义Job类为HelloQuartz类
					.withIdentity("job1","group1") // 定义name/group
					.usingJobData("name","quartz") // 定义属性
					.build();
			
			//加入这个调度
			scheduler.scheduleJob(job, trigger);
			
			//启动
			scheduler.start();
					
			// 运行一段时间后关闭
			Thread.sleep(10000);
			scheduler.shutdown(true);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}


}
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class HelloJob implements Job {
	public void execute(JobExecutionContext context) throws JobExecutionException
	{
		JobDetail detail = context.getJobDetail();
		String name = detail.getJobDataMap().getString("name");
		System.out.println("hello from " + name + " at " + new Date());
	}
}

你可能感兴趣的:(JAVA多线程)