多线程与定时任务

需求:将三张表的查询结果 定时保存到另一张表中

 可以采用串行执行 也可以用并行执行,提高查询速度此处用并行的方式,充分利用cup资源,通过Callable接口实现多线程,实现Callable重写call方法;

实现Callable和实现Runnable类似,但是功能更强大,具体表现在:
a.可以在任务结束后提供一个返回值,Runnable不行;
b.call方法可以抛出异常,Runnable的run方法不行;
c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值);
1、Callable接口介绍:
(1)java.util.concurrent.Callable是一个泛型接口,只有一个call()方法;
(2)call()方法抛出异常Exception异常,且返回一个指定的泛型类对象;
2、Callable接口实现多线程的应用场景
(1)当父线程想要获取子线程的运行结果时;
3、使用Callable接口实现多线程的步骤
(1)第一步:创建Callable子类的实例化对象;
(2)第二步:创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中(注意:FutureTask实现了Runnable接口和Future接口);
 (3)第三步:实例化Thread对象,并在构造方法中传入FurureTask对象;
 (4)第四步:启动线程;
@Component
public class TaskDemo {

    @Autowired
    AgeMapper ageMapper;
    @Autowired
    NameMapper nameMapper;
    @Autowired
    SexMapper sexMapper;
    @Autowired
    PropertyMapper propertyMapper;

    @Scheduled(cron = "0 38 16 * * ?")//每天下午16:38 执行
    //@Scheduled(cron = "0 0/2 0 * * ?")//每两分钟执行一次
    public void test() throws ExecutionException, InterruptedException {
        //创建线程池
        Property property = new Property();

        ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);

        Future agefuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectAgeById", new Object[]{"1"}));
        Future namefuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectNameById", new Object[]{"1"}));
        Future sexfuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectSexById", new Object[]{"1"}));


        //用do while 保证三个线程都执行完毕
        do {
            System.out.println("任务正在执行中。。。。。");
        } while (!agefuture.isDone() && !namefuture.isDone() && !sexfuture.isDone());
        Age age = (Age) agefuture.get();
        Name name = (Name) namefuture.get();
        Sex sex = (Sex) sexfuture.get();
        property.setAge(age.getAge());
        property.setName(name.getName());
        property.setSex(sex.getSex());
        System.out.println("开始写入数据");
        propertyMapper.insert(property);
        System.out.println("写入数据完毕");
        poolExecutor.shutdown();
    }


    public Age selectAgeById(String id) {
        return ageMapper.selectById("1");
    }

    public Name selectNameById(String id) {
        return nameMapper.selectById("1");
    }

    public Sex selectSexById(String id) {
        return sexMapper.selectById("1");
    }


    class SelectObjectThread<T> implements Callable<T> {
        private Object object;
        private String methodName;
        private Object[] objects;

        public SelectObjectThread(Object object, String methodName, Object[] objects) {
            this.object = object;
            this.methodName = methodName;
            this.objects = objects;
        }

        @Override
        public T call() throws Exception {
            long start = System.currentTimeMillis();
            Method method = object.getClass().getMethod(methodName, String.class);// String.class调用方法的参数类型
        /* String name = method.getName();
        if (name.equals("selectAgeById")){
      Thread.sleep(20000);
        }*/
        T t = (T) method.invoke(object, objects);
            //System.out.println(t);
            long end = System.currentTimeMillis();
            System.out.println("执行" + methodName + "查询用时:" + (end - start));
            return t;
        }
    }


}
@SpringBootApplication
@MapperScan({"com.yckj.mapper"})
@EnableScheduling
public class TimerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TimerApplication.class, args);
    }

}

  

原文地址:https://www.cnblogs.com/yscec/p/13476592.html