java几种线程调度

来源:互联网 发布:淘宝皇冠和天猫哪个好? 编辑:程序博客网 时间:2024/06/08 09:58
  • Timer实现
  • ScheduledExcetor实现
  • 使用Quarzt实现
    使用java.util.Timer实现调度,功能较单一

(1) Timer实现

public static void main(String[] args) {        Timer timer = new Timer();        timer.schedule(new TimerTask() {            int i=0;            @Override            public void run() {                System.out.println(i);                i++;            }        },10000,1000);    }

Timer依靠Timer和TimerTask实现定时调度。其中Timer只要实现定义任务的延时时间(delay)和定时调度(period)。TimerTask需要在run方法中实现具体的业务。
Timer实现原理是:一个queue和一个线程。Timer将接受的任务存放于queue中。TimerThread会轮询所有的任务,按照Timer设置的时间休眠和执行任务。
由于Timer基于list实现,一个任务的延迟会影响到后面所有的任务的执行。

(2) ScheduledExcetor实现

  • schedule
    实现延迟调度,不能实现周期调度
public static void main(String[] args) {        ScheduledExecutorService service = Executors.newScheduledThreadPool(2);        System.out.println("begin");        for (int a = 0; a < 10; a++) {            final int count = a;            service.schedule(new Runnable() {                @Override                public void run() {                    System.out.println(count);                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }, 1, TimeUnit.SECONDS);        }    }

输出结果为:先输出begin,延迟1秒,输出0 1,线程休眠1秒,输出2 3….

  • scheduleAtFixedRate(Runnable runnable,long initialDelay,long period,TimeUnit unit)
    字面意思可以理解为固定速率调度。不考虑其他因素每过period秒调度一次,基于规定时间进行调度。
public static void main(String[] args) {        ScheduledExecutorService service = Executors.newScheduledThreadPool(2);        service.scheduleAtFixedRate(new Runnable() {            @Override            public void run() {                System.out.println("1");            }        }, 2,2, TimeUnit.SECONDS);    }
  • scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)
    调度时间取决于每次任务执行的时间长短

(3) Quartz实现

  • 单机实现Quartz
    单机实现Quartz需要quartz、slf4j、logj等jar的支持。
    使用Quartz实现定时调度,需要:Scheduler、Job、以及Trigger
    其中Job需要指定执行的任务:JobBuilder.newJob(MyQuarz.class)
    Trigger需要指定调度的策略:.withSchedule(builder)
    Scheduler将两者组合起来。
public static void main(String[] args){        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            JobDataMap datamap = new JobDataMap();            datamap.put("name","job1");            JobDetail detail = JobBuilder.newJob(MyQuartz.class)                    .withIdentity("job1","lin_group")                    .setJobData(datamap)                    .build();            SimpleScheduleBuilder builder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(100, 5);            Trigger trigger =  TriggerBuilder.newTrigger()                    .withIdentity("trigger1", "lin_group")                    .startNow()                    .withSchedule(builder)                    .build();            scheduler.scheduleJob(detail,trigger);            scheduler.start();        } catch (SchedulerException e) {            e.printStackTrace();        }    }

具体需要执行的方法:MyQuartz

public class MyQuartz implements Job{    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        Object name = jobExecutionContext.getJobDetail().getJobDataMap().get("name");        System.out.println(name.toString());    }}
  • 配合Spring框架使用
    使用配置文件来定义调度策略
    1、创建quartz.xml文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    <bean id="printJobTimer" class="xyz.chanjkf.utils.quarz.PrintJobTimer"/>    <bean id="printJobTimerDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">        <!--  被调度类:PrintJobTimer -->        <property name="targetObject" ref="printJobTimer"/>        <!--  被调度方法:print() -->        <property name="targetMethod" value="print"/>        <property name="concurrent" value="false"/>    </bean>    <!-- ======================== 调度触发器 ======================== -->    <bean id="printJobTimerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">        <property name="jobDetail" ref="printJobTimerDetail"></property>        <property name="cronExpression">            <value>0 0 */2 * * ?</value>        </property>    </bean>    <!-- ======================== 调度工厂 ======================== -->    <bean id="SpringJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">        <property name="triggers">            <list>                <ref bean="printJobTimerTrigger"/>            </list>        </property>    </bean></beans>

2、调度类以及方法:

public class PrintJobTimer {    public void print(){        System.out.println("hello");    }}

3、在web.xml中声明quartz.xml

<context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:spring/applicationContext.xml,classpath:spring-security.xml,classpath:quarz.xml</param-value>    </context-param>

在spring中也可以使用另一种方式创建

@Component("StartupListener")public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {    private static boolean isStart = false;    final static DXPLog dxpLog = new DXPLog(StartupListener.class);    @Override    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {        if(!isStart) {            isStart = true;            startPrint();        }    }    private void startPrint() {        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            JobDetail detail = JobBuilder                    .newJob(PrintJob.class)                    .withIdentity("job1", "group1")                    .build();            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(10, 1);            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0 * * ?");            Trigger trigger = TriggerBuilder                    .newTrigger()                    .withIdentity("trigger1", "group1")                    .startNow()                    .withSchedule(simpleScheduleBuilder)                    .build();            scheduler.scheduleJob(detail, trigger);            scheduler.start();        } catch (SchedulerException e) {            e.printStackTrace();        }    }}

下面再记录一下T两种常用Trigger

  • SimpleTrigger
SimpleScheduleBuilder builder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(20);
 1、repeatSecondlyForever() 每1秒执行一次,直到程序停止 2、repeatSecondlyForever(20); 每20秒执行一次,直到程序停止 3、repeatSecondlyForTotalCount(20); 每1秒执行一次,一共执行20次 4、repeatSecondlyForTotalCount(20, 10) 每10秒执行一次,一共执行20次

- CronTrigger

CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0 * * ?");
1、创建一个每三小时执行的 CronTrigger,且从每小时的整点开始执行:   0 0 0/3  * * ?2、2005年每天10点15分触发   0 15 10 * * ? 20053、每天下午的 2点到2点59分(整点开始,每隔5分触发)   0 0/5 14 * * ?4、每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分   0 0/5 14,18 * * ?5、从周一到周五每天上午的10点15分触发   0 15 10 ? * MON-FRI6、每月的第一个中午开始每隔5天触发一次   0 0 12 1/5 * ?

部分内容参考https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/