场景需求:在执行某个方法的两小时之后进行某个操作
涉及:定时任务、哈希表
需要注意:业务逻辑层是单一实例的,所以在定时任务类内操作业务逻辑层的某个属性和在业务逻辑层内操作的都是同一个。
疑问:ThreadPoolTaskScheduler线程池需不需要规定线程数量?

定时任务类

@Component
public class VideoRecorderScheduler {
    private final TestService testService = SpringContextHolder.getBean(TestService.class);
	
    public VideoRecorderScheduler(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    // 开启定时任务
    public ScheduledFuture startVideoRecording(){
        //System.out.println("开始啦--------------------");
        // 记录开启时间
        startTime = System.currentTimeMillis();
        //开启任务 两小时后自动执行停止任务 可以改成两分钟方便测试
        stopTask = taskScheduler.schedule(this::stopVideoRecording, Instant.now().plusSeconds(2 * 60 * 60));
        return stopTask;
    }

    // 停止定时任务
    private void stopVideoRecording(){
        // 执行其他操作
        // ...
		
        // 关闭定时任务
        if (stopTask != null && !stopTask.isCancelled()) {
            stopTask.cancel(true);
            testService.getScheduledTasks().remove(taskId);
        }
    }
}

测试类 testService

@Service
public class TestService(){
    // 存放定时任务的map
    @Getter
    private Map<String, ScheduledFuture<?>> scheduledTasks = new IdentityHashMap<>();
	
    public void start(){
	//开启定时任务
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); // 创建一个ThreadPoolTaskScheduler对象
        taskScheduler.initialize(); // 初始化taskScheduler
        VideoRecorderScheduler videoRecorder = new VideoRecorderScheduler(taskScheduler); // 创建一个带参数的VideoRecorder对象
        //放入map
        ScheduledFuture stopTask = videoRecorder.startVideoRecording();
        scheduledTasks.put(taskId,stopTask);
    }
	
	public void stop(){
	    //取消定时任务
            ScheduledFuture<?> stopTask = scheduledTasks.get(taskId);
            scheduledTasks.remove(taskId);
            if (stopTask != null && !stopTask.isCancelled()) {
                stopTask.cancel(true);
            }
	}
}