java几种线程调度

  • 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 * * ? 2005
3、每天下午的 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-FRI
6、每月的第一个中午开始每隔5天触发一次
   0 0 12 1/5 * ?

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值