关于多线程返回值Future类的使用(基于springboot)

java创建线程有2种方式,一种是集成Thread类,一种是实现runnable接口。这两种方法在执行线程过后都无法获取执行出来的结果。如果想获取结果就必须通过共享变量或线程间的通讯的方式。

自jdk1.5之后,提供了Future和Callable,可以解决上述问题。

首先说下springboot对其的简单实现。

配置线程池,代码如下:

package com.nsu.edu.cn.lemon.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 异步线程池配置类
 * @author zhangpengyu
 * @date 2019-07-04
 */
@Configuration
@EnableAsync
public class TaskExecutorConfiguration {

    @Bean
    public TaskExecutor myAsync() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(100);
        executor.setMaxPoolSize(200);
        executor.setQueueCapacity(500);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("zpyAsync-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        executor.afterPropertiesSet();
        return executor;
    }
}

添加异步方法:

package com.nsu.edu.cn.lemon.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;

@Component
public class AsyncTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncTask.class);

    @Async
    public Future getTotalHitsFuture() throws InterruptedException {
        LOGGER.info("get total . ");
        Thread.sleep(1000);
        return new AsyncResult<>(1L);
    }
}

添加定时任务:

package com.nsu.edu.cn.lemon.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Component
public class MyTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyTask.class);

    @Autowired
    private AsyncTask asyncTask;

    @Scheduled(cron = "0/30 * * * * *")
    public void myFunction() throws ExecutionException, InterruptedException {
        System.out.println("task start . ");
        Future future0 = asyncTask.getTotalHitsFuture();
        Future future1 = asyncTask.getTotalHitsFuture();
        Future future2 = asyncTask.getTotalHitsFuture();
        Long total = future0.get()+future1.get()+future2.get();
        LOGGER.info(total+"===");
    }
}

当然别忘记在启动类添加@EnableScheduling注解,启动效果如下图:

只需要1秒就能把3个线程的结果都返回,节省了时间

你可能感兴趣的:(日积月累)