牛客网项目——前置技术(十一):任务执行和调度


在这里插入图片描述
ExecutorService
ScheduledExecutorService

ThredPoolTaskExecutor
ThredPoolTaskScheduler

Spring Quartz

1. 分布式换环境下的定时任务问题

Schedule每隔一段时间做同样的事情,做的任务会重复
在这里插入图片描述
Quartz定时任务驱动的参数存到数据库里,通过排队加锁等这样的机制实现共享
在这里插入图片描述

2. JDK线程池

注意:main方法的线程如果不挂掉会一直等着它执行,但是juint方法中线程如果后面没有逻辑立马就结束了。解决方法启动之后等一下,让当前线程阻塞一会,但是sleep方法又经常抛异常,为了调起来方便把sleep封装一下

private void sleep(long m) {
    try {
        Thread.sleep(m);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

2.1 普通线程池 ExecutorService

  1. 通过newFixedThreadPool工厂实例化普通线程池
  2. 实现一个Runnable()方法的匿名实现,任务为logger.debug("Hello ExecutorService");
  3. submit(执行)十次
  4. sleep10000毫秒
    在这里插入图片描述

2.2 定时任务线程池ScheduledExecutorService

  1. 通过newScheduledThreadPool工厂实例化定时任务线程池
  2. 实现一个Runnable()方法的匿名实现,任务为logger.debug("Hello ExecutorService");
  3. 调用scheduledExecutorService的方法scheduleAtFixedRate,参数为:传入任务,延迟时间,时间间隔,数字单位:scheduledExecutorService.scheduleAtFixedRate(task, 10000, 1000, TimeUnit.MILLISECONDS);
  4. sleep10000毫秒
    在这里插入图片描述

3. Spring线程池

3.1 配置文件 application.properties

3.1.1 普通线程池

  1. core-size:核心线程数量
  2. max-size:自动扩容上限
  3. queue-capacity:队列容量,最大容量也不够用时,放入队列进行缓冲
# TaskExecutionProperties
spring.task.execution.pool.core-size=5
spring.task.execution.pool.max-size=15
spring.task.execution.pool.queue-capacity=100

3.1.2 定时任务线程池

  1. size:线程数量
# TaskSchedulingProperties
spring.task.scheduling.pool.size=5

3.2 配置类 ThreadPoolConfig

@Configuration
@EnableScheduling
@EnableAsync
public class ThreadPoolConfig {
}

3.3 Spring普通线程池:ThreadPoolTaskExecutor

  1. 注入普通线程池ThreadPoolTaskExecutor
  2. 实现一个Runnable()方法的匿名实现,任务为logger.debug("Hello ExecutorService");
  3. submit(执行)十次
  4. sleep10000毫秒
  5. 比JDK自带的线程池更灵活
    在这里插入图片描述

3.4 Spring定时任务线程池:ThreadPoolTaskScheduler

  1. 注入定时任务线程池ThreadPoolTaskScheduler
  2. 实现一个Runnable()方法的匿名实现,任务为logger.debug("Hello ExecutorService");
  3. 调用taskScheduler.scheduleAtFixedRate,线程任务,开始时间,时间间隔
  4. sleep10000毫秒

3.5 Spring普通线程池(简化)

3.5.1 在任一service下写入以下语句

如在AlphaService中

// 让该方法在多线程环境下,被异步的调用.
@Async
public void execute1() {
    logger.debug("execute1");
}

3.5.2 ThreadPoolTests

@Autowired
private AlphaService alphaService;

// 5.Spring普通线程池(简化)
@Test
public void testThreadPoolTaskExecutorSimple() {
    for (int i = 0; i < 10; i++) {
        alphaService.execute1();
    }
    sleep(10000);
}

3.6 Spring定时任务线程池(简化)

3.6.1 在任一service下写入以下语句

如在AlphaService中

/*@Scheduled(initialDelay = 10000, fixedRate = 1000)*/
public void execute2() {
    logger.debug("execute2");
}

3.6.2 ThreadPoolTests

// 6.Spring定时任务线程池(简化)
@Test
public void testThreadPoolTaskSchedulerSimple() {
    sleep(30000);
}

4. Spring Quartz

4.1 pom.xml 导入包

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

4.2 核心组件

  1. scheduler 接口:核心调度工具,所有任务由这一接口调用
  2. job:定义任务,重写execute方法
  3. JobDetail接口:配置描述
  4. Trigger接口:什么时候运行,以什么样的频率运行

启动后,配置信息存入数据库,只在第一次启用

4.3 导入数据库

  1. qrtz_job_details:job详情配置描述表
  2. qrtz_simple_triggers:触发器相关配置简述
  3. qrtz_jtriggers:触发器相关完整配置
  4. qrtz_scheduler:定时器状态
  5. qrtz_locks:定时器锁

4.4 AlphaJob

打印当前线程名字

public class AlphaJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println(Thread.currentThread().getName() + ": execute a quartz job.");
    }
}

4.5 QuartzConfig

配置的作用事第一次被读取到数据库,后面就不用了

FactoryBean可简化Bean的实例化过程:
1. 通过FactoryBean封装Bean的实例化过程.
2. 将FactoryBean装配到Spring容器里.
3. 将FactoryBean注入给其他的Bean.
4. 该Bean得到的是FactoryBean所管理的对象实例.

  1. 配置JobDetail
    1. 实例化JobDetailFactoryBean
    2. 声明管理的管理的是谁.setJobClass
    3. 声明job任务的名字.setName
    4. 声明任务属于的组.setGroup
    5. 声明任务是否长久保存.setDurability
    6. 声明任务是否可恢复.setRequestsRecovery
// 配置JobDetail
@Bean
public JobDetailFactoryBean alphaJobDetail() {
    JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
    factoryBean.setJobClass(AlphaJob.class);
    factoryBean.setName("alphaJob");
    factoryBean.setGroup("alphaJobGroup");
    factoryBean.setDurability(true);
    factoryBean.setRequestsRecovery(true);
    return factoryBean;
}
  1. 配置Trigger
    1. 实例化SimpleTriggerFactoryBean
    2. 声明管理的管理的是谁.setJobClass
    3. 声明job任务的名字.setName
    4. 声明任务属于的组.setGroup
    5. 声明任务执行的频率.setRepeatInterval
    6. 声明Trigger的存储状态类型.setJobDataMap
// 配置Trigger(SimpleTriggerFactoryBean, CronTriggerFactoryBean)
@Bean
public SimpleTriggerFactoryBean alphaTrigger(JobDetail alphaJobDetail) {
    SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
    factoryBean.setJobDetail(alphaJobDetail);
    factoryBean.setName("alphaTrigger");
    factoryBean.setGroup("alphaTriggerGroup");
    factoryBean.setRepeatInterval(3000);
    factoryBean.setJobDataMap(new JobDataMap());
    return factoryBean;
}

4.6 Quartz底层线程池配置

# QuartzProperties
spring.quartz.job-store-type=jdbc #存储方式
spring.quartz.scheduler-name=communityScheduler #调度器名字
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO #调度器id自动生成
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX #存入数据库的类
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate #驱动
spring.quartz.properties.org.quartz.jobStore.isClustered=true #采用集群
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool #用哪个线程池
spring.quartz.properties.org.quartz.threadPool.threadCount=5 #线程池数量

4.7 写程序删除job:QuartzTests

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class QuartzTests {

    @Autowired
    private Scheduler scheduler;

    @Test
    public void testDeleteJob() {
        try {
            boolean result = scheduler.deleteJob(new JobKey("alphaJob", "alphaJobGroup"));
            System.out.println(result);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平什么阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值